diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2013-12-22 00:04:03 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2013-12-22 00:04:03 +0000 |
| commit | f8af5cf600354830d4ccf59732403f0f073eccb9 (patch) | |
| tree | 2ba0398b4c42ad4f55561327538044fd2c925a8b /lib/Target/XCore | |
| parent | 59d6cff90eecf31cb3dd860c4e786674cfdd42eb (diff) | |
Notes
Diffstat (limited to 'lib/Target/XCore')
22 files changed, 490 insertions, 245 deletions
diff --git a/lib/Target/XCore/CMakeLists.txt b/lib/Target/XCore/CMakeLists.txt index d5bfddc23e0f8..3fa3b34245d7f 100644 --- a/lib/Target/XCore/CMakeLists.txt +++ b/lib/Target/XCore/CMakeLists.txt @@ -22,10 +22,11 @@ add_llvm_target(XCoreCodeGen XCoreSubtarget.cpp XCoreTargetMachine.cpp XCoreTargetObjectFile.cpp + XCoreTargetTransformInfo.cpp XCoreSelectionDAGInfo.cpp ) -add_dependencies(LLVMXCoreCodeGen intrinsics_gen) +add_dependencies(LLVMXCoreCodeGen XCoreCommonTableGen intrinsics_gen) add_subdirectory(Disassembler) add_subdirectory(InstPrinter) diff --git a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp index a2ae40c58a6ec..9c20abd4c6c70 100644 --- a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp +++ b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp @@ -29,7 +29,7 @@ namespace { /// \brief A disassembler class for XCore. class XCoreDisassembler : public MCDisassembler { - const MCRegisterInfo *RegInfo; + OwningPtr<const MCRegisterInfo> RegInfo; public: XCoreDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info) : MCDisassembler(STI), RegInfo(Info) {} @@ -42,7 +42,7 @@ public: raw_ostream &vStream, raw_ostream &cStream) const; - const MCRegisterInfo *getRegInfo() const { return RegInfo; } + const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } }; } @@ -53,7 +53,7 @@ static bool readInstruction16(const MemoryObject ®ion, uint8_t Bytes[4]; // We want to read exactly 2 Bytes of data. - if (region.readBytes(address, 2, Bytes, NULL) == -1) { + if (region.readBytes(address, 2, Bytes) == -1) { size = 0; return false; } @@ -69,7 +69,7 @@ static bool readInstruction32(const MemoryObject ®ion, uint8_t Bytes[4]; // We want to read exactly 4 Bytes of data. - if (region.readBytes(address, 4, Bytes, NULL) == -1) { + if (region.readBytes(address, 4, Bytes) == -1) { size = 0; return false; } diff --git a/lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.cpp b/lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.cpp index 1cfdbda003b53..3d1c4745d6ac8 100644 --- a/lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.cpp +++ b/lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.cpp @@ -13,7 +13,7 @@ using namespace llvm; void XCoreMCAsmInfo::anchor() { } -XCoreMCAsmInfo::XCoreMCAsmInfo(const Target &T, StringRef TT) { +XCoreMCAsmInfo::XCoreMCAsmInfo(StringRef TT) { SupportsDebugInformation = true; Data16bitsDirective = "\t.short\t"; Data32bitsDirective = "\t.long\t"; @@ -23,10 +23,14 @@ XCoreMCAsmInfo::XCoreMCAsmInfo(const Target &T, StringRef TT) { PrivateGlobalPrefix = ".L"; AscizDirective = ".asciiz"; - WeakDefDirective = "\t.weak\t"; - WeakRefDirective = "\t.weak\t"; + + HiddenVisibilityAttr = MCSA_Invalid; + HiddenDeclarationVisibilityAttr = MCSA_Invalid; + ProtectedVisibilityAttr = MCSA_Invalid; // Debug HasLEB128 = true; + ExceptionsType = ExceptionHandling::DwarfCFI; + DwarfRegNumForCFI = true; } diff --git a/lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.h b/lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.h index 076777541e33d..e53c96b8f7455 100644 --- a/lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.h +++ b/lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.h @@ -14,16 +14,16 @@ #ifndef XCORETARGETASMINFO_H #define XCORETARGETASMINFO_H -#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCAsmInfoELF.h" namespace llvm { class StringRef; class Target; - class XCoreMCAsmInfo : public MCAsmInfo { + class XCoreMCAsmInfo : public MCAsmInfoELF { virtual void anchor(); public: - explicit XCoreMCAsmInfo(const Target &T, StringRef TT); + explicit XCoreMCAsmInfo(StringRef TT); }; } // namespace llvm diff --git a/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp b/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp index c1773653f5fb5..10bb6dfa928a3 100644 --- a/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp +++ b/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp @@ -51,13 +51,13 @@ static MCSubtargetInfo *createXCoreMCSubtargetInfo(StringRef TT, StringRef CPU, return X; } -static MCAsmInfo *createXCoreMCAsmInfo(const Target &T, StringRef TT) { - MCAsmInfo *MAI = new XCoreMCAsmInfo(T, TT); +static MCAsmInfo *createXCoreMCAsmInfo(const MCRegisterInfo &MRI, + StringRef TT) { + MCAsmInfo *MAI = new XCoreMCAsmInfo(TT); // Initial state of the frame pointer is SP. - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(XCore::SP, 0); - MAI->addInitialFrameState(0, Dst, Src); + MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, XCore::SP, 0); + MAI->addInitialFrameState(Inst); return MAI; } diff --git a/lib/Target/XCore/README.txt b/lib/Target/XCore/README.txt index b69205b49b6ca..28d551a1024ce 100644 --- a/lib/Target/XCore/README.txt +++ b/lib/Target/XCore/README.txt @@ -5,3 +5,4 @@ To-do * Tailcalls * Investigate loop alignment * Add builtins + diff --git a/lib/Target/XCore/XCore.h b/lib/Target/XCore/XCore.h index 2f375fc952ca6..73c310be03442 100644 --- a/lib/Target/XCore/XCore.h +++ b/lib/Target/XCore/XCore.h @@ -31,6 +31,8 @@ namespace llvm { CodeGenOpt::Level OptLevel); ModulePass *createXCoreLowerThreadLocalPass(); + ImmutablePass *createXCoreTargetTransformInfoPass(const XCoreTargetMachine *TM); + } // end namespace llvm; #endif diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp index e177ad300cfe3..c03dfe61504e5 100644 --- a/lib/Target/XCore/XCoreAsmPrinter.cpp +++ b/lib/Target/XCore/XCoreAsmPrinter.cpp @@ -36,6 +36,7 @@ #include "llvm/MC/MCInst.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCExpr.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" @@ -49,7 +50,6 @@ namespace { class XCoreAsmPrinter : public AsmPrinter { const XCoreSubtarget &Subtarget; XCoreMCInstLower MCInstLowering; - void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); public: explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget<XCoreSubtarget>()), @@ -76,7 +76,6 @@ namespace { void EmitInstruction(const MachineInstr *MI); void EmitFunctionBodyStart(); void EmitFunctionBodyEnd(); - virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; }; } // end of anonymous namespace @@ -85,16 +84,17 @@ void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) { GV->hasWeakLinkage()) || GV->hasLinkOnceLinkage()) && "Unexpected linkage"); if (ArrayType *ATy = dyn_cast<ArrayType>( - cast<PointerType>(GV->getType())->getElementType())) { - OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global); - // FIXME: MCStreamerize. - OutStreamer.EmitRawText(StringRef(".globound")); - OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName())); - OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements())); + cast<PointerType>(GV->getType())->getElementType())) { + + MCSymbol *SymGlob = OutContext.GetOrCreateSymbol( + Twine(Sym->getName() + StringRef(".globound"))); + OutStreamer.EmitSymbolAttribute(SymGlob, MCSA_Global); + OutStreamer.EmitAssignment(SymGlob, + MCConstantExpr::Create(ATy->getNumElements(), + OutContext)); if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) { // TODO Use COMDAT groups for LinkOnceLinkage - OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+ - ".globound"); + OutStreamer.EmitSymbolAttribute(SymGlob, MCSA_Weak); } } } @@ -109,7 +109,7 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM)); - MCSymbol *GVSym = Mang->getSymbol(GV); + MCSymbol *GVSym = getSymbol(GV); const Constant *C = GV->getInitializer(); unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); @@ -216,7 +216,7 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum, O << *MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: - O << *Mang->getSymbol(MO.getGlobal()); + O << *getSymbol(MO.getGlobal()); break; case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); @@ -242,45 +242,14 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum, bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant,const char *ExtraCode, raw_ostream &O) { - // Does this asm operand have a single letter operand modifier? - if (ExtraCode && ExtraCode[0]) - if (ExtraCode[1] != 0) return true; // Unknown modifier. - - switch (ExtraCode[0]) { - default: - // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); - } - - printOperand(MI, OpNo, O); - return false; -} - -void XCoreAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, - raw_ostream &OS) { - unsigned NOps = MI->getNumOperands(); - assert(NOps == 4); - OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; - // cast away const; DIetc do not take const operands for some reason. - DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); - OS << V.getName(); - OS << " <- "; - // Frame address. Currently handles register +- offset only. - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); - OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); - OS << ']'; - OS << "+"; - printOperand(MI, NOps-2, OS); -} + // Print the operand if there is no operand modifier. + if (!ExtraCode || !ExtraCode[0]) { + printOperand(MI, OpNo, O); + return false; + } -MachineLocation XCoreAsmPrinter:: -getDebugValueLocation(const MachineInstr *MI) const { - // Handles frame addresses emitted in XCoreInstrInfo::emitFrameIndexDebugValue. - assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); - assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm() && - "Unexpected MachineOperand types"); - return MachineLocation(MI->getOperand(0).getReg(), - MI->getOperand(1).getImm()); + // Otherwise fallback on the default implementation. + return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); } void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) { @@ -288,15 +257,8 @@ void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) { raw_svector_ostream O(Str); switch (MI->getOpcode()) { - case XCore::DBG_VALUE: { - if (isVerbose() && OutStreamer.hasRawTextSupport()) { - SmallString<128> TmpStr; - raw_svector_ostream OS(TmpStr); - PrintDebugValueComment(MI, OS); - OutStreamer.EmitRawText(StringRef(OS.str())); - } - return; - } + case XCore::DBG_VALUE: + llvm_unreachable("Should be handled target independently"); case XCore::ADD_2rus: if (MI->getOperand(2).getImm() == 0) { O << "\tmov " diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp index beeb07f831c67..c34b35c140f96 100644 --- a/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/lib/Target/XCore/XCoreFrameLowering.cpp @@ -30,10 +30,6 @@ using namespace llvm; // helper functions. FIXME: Eliminate. -static inline bool isImmUs(unsigned val) { - return val <= 11; -} - static inline bool isImmU6(unsigned val) { return val < (1 << 6); } @@ -92,11 +88,16 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineModuleInfo *MMI = &MF.getMMI(); + const MCRegisterInfo *MRI = MMI->getContext().getRegisterInfo(); const XCoreInstrInfo &TII = *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); + if (MFI->getMaxAlignment() > getStackAlignment()) + report_fatal_error("emitPrologue unsupported alignment: " + + Twine(MFI->getMaxAlignment())); + bool FP = hasFP(MF); const AttributeSet &PAL = MF.getFunction()->getAttributes(); @@ -116,9 +117,9 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { } bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(MF); + bool saveLR = XFI->getUsesLR(); // Do we need to allocate space on the stack? if (FrameSize) { - bool saveLR = XFI->getUsesLR(); bool LRSavedOnEntry = false; int Opcode; if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { @@ -132,34 +133,28 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); if (emitFrameMoves) { - std::vector<MachineMove> &Moves = MMI->getFrameMoves(); - // Show update of SP. MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); - - MachineLocation SPDst(MachineLocation::VirtualFP); - MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); - Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); - + MMI->addFrameInst(MCCFIInstruction::createDefCfaOffset(FrameLabel, + -FrameSize*4)); if (LRSavedOnEntry) { - MachineLocation CSDst(MachineLocation::VirtualFP, 0); - MachineLocation CSSrc(XCore::LR); - Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc)); + unsigned Reg = MRI->getDwarfRegNum(XCore::LR, true); + MMI->addFrameInst(MCCFIInstruction::createOffset(FrameLabel, Reg, 0)); } } - if (saveLR) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); - MBB.addLiveIn(XCore::LR); + } + if (saveLR) { + int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); + storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); + MBB.addLiveIn(XCore::LR); - if (emitFrameMoves) { - MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); - MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); - MachineLocation CSSrc(XCore::LR); - MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc)); - } + if (emitFrameMoves) { + MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); + unsigned Reg = MRI->getDwarfRegNum(XCore::LR, true); + MMI->addFrameInst(MCCFIInstruction::createOffset(SaveLRLabel, Reg, + LRSpillOffset)); } } @@ -172,37 +167,34 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { if (emitFrameMoves) { MCSymbol *SaveR10Label = MMI->getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveR10Label); - MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); - MachineLocation CSSrc(XCore::R10); - MMI->getFrameMoves().push_back(MachineMove(SaveR10Label, CSDst, CSSrc)); + unsigned Reg = MRI->getDwarfRegNum(XCore::R10, true); + MMI->addFrameInst(MCCFIInstruction::createOffset(SaveR10Label, Reg, + FPSpillOffset)); } // Set the FP from the SP. unsigned FramePtr = XCore::R10; - BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr) - .addImm(0); + BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr).addImm(0); if (emitFrameMoves) { // Show FP is now valid. MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); - MachineLocation SPDst(FramePtr); - MachineLocation SPSrc(MachineLocation::VirtualFP); - MMI->getFrameMoves().push_back(MachineMove(FrameLabel, SPDst, SPSrc)); + unsigned Reg = MRI->getDwarfRegNum(FramePtr, true); + MMI->addFrameInst(MCCFIInstruction::createDefCfaRegister(FrameLabel, + Reg)); } } if (emitFrameMoves) { // Frame moves for callee saved. - std::vector<MachineMove> &Moves = MMI->getFrameMoves(); std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels = XFI->getSpillLabels(); for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { MCSymbol *SpillLabel = SpillLabels[I].first; CalleeSavedInfo &CSI = SpillLabels[I].second; int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); - unsigned Reg = CSI.getReg(); - MachineLocation CSDst(MachineLocation::VirtualFP, Offset); - MachineLocation CSSrc(Reg); - Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); + unsigned Reg = MRI->getDwarfRegNum(CSI.getReg(), true); + MMI->addFrameInst(MCCFIInstruction::createOffset(SpillLabel, Reg, + Offset)); } } } @@ -213,6 +205,7 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); const XCoreInstrInfo &TII = *static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo()); + XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); DebugLoc dl = MBBI->getDebugLoc(); bool FP = hasFP(MF); @@ -237,28 +230,32 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, report_fatal_error("emitEpilogue Frame size too big: " + Twine(FrameSize)); } - if (FrameSize) { - XCoreFunctionInfo *XFI = MF.getInfo<XCoreFunctionInfo>(); + if (FP) { + // Restore R10 + int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); + FPSpillOffset += FrameSize*4; + loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII); + } - if (FP) { - // Restore R10 - int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - FPSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII); - } - bool restoreLR = XFI->getUsesLR(); - if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - LRSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII); - restoreLR = false; - } + bool restoreLR = XFI->getUsesLR(); + if (restoreLR && + (FrameSize == 0 || MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0)) { + int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); + LRSpillOffset += FrameSize*4; + loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII); + restoreLR = false; + } + + if (FrameSize) { if (restoreLR) { // Fold prologue into return instruction + assert(MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0); assert(MBBI->getOpcode() == XCore::RETSP_u6 || MBBI->getOpcode() == XCore::RETSP_lu6); int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; - BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); + MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); + for (unsigned i = 3, e = MBBI->getNumOperands(); i < e; ++i) + MIB->addOperand(MBBI->getOperand(i)); // copy any variadic operands MBB.erase(MBBI); } else { int Opcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; diff --git a/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/lib/Target/XCore/XCoreISelDAGToDAG.cpp index eb29b5001080a..e28f84fec2a98 100644 --- a/lib/Target/XCore/XCoreISelDAGToDAG.cpp +++ b/lib/Target/XCore/XCoreISelDAGToDAG.cpp @@ -37,13 +37,11 @@ using namespace llvm; /// namespace { class XCoreDAGToDAGISel : public SelectionDAGISel { - const XCoreTargetLowering &Lowering; const XCoreSubtarget &Subtarget; public: XCoreDAGToDAGISel(XCoreTargetMachine &TM, CodeGenOpt::Level OptLevel) : SelectionDAGISel(TM, OptLevel), - Lowering(*TM.getTargetLowering()), Subtarget(*TM.getSubtargetImpl()) { } SDNode *Select(SDNode *N); @@ -61,7 +59,7 @@ namespace { if (!isMask_32(value)) { return false; } - int msksize = 32 - CountLeadingZeros_32(value); + int msksize = 32 - countLeadingZeros(value); return (msksize >= 1 && msksize <= 8) || msksize == 16 || msksize == 24 || msksize == 32; } @@ -109,7 +107,7 @@ bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base, } SDNode *XCoreDAGToDAGISel::Select(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); switch (N->getOpcode()) { default: break; case ISD::Constant: { @@ -117,7 +115,7 @@ SDNode *XCoreDAGToDAGISel::Select(SDNode *N) { if (immMskBitp(N)) { // Transformation function: get the size of a mask // Look for the first non-zero bit - SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(Val)); + SDValue MskSize = getI32Imm(32 - countLeadingZeros((uint32_t)Val)); return CurDAG->getMachineNode(XCore::MKMSK_rus, dl, MVT::i32, MskSize); } @@ -125,7 +123,7 @@ SDNode *XCoreDAGToDAGISel::Select(SDNode *N) { SDValue CPIdx = CurDAG->getTargetConstantPool(ConstantInt::get( Type::getInt32Ty(*CurDAG->getContext()), Val), - TLI.getPointerTy()); + getTargetLowering()->getPointerTy()); SDNode *node = CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32, MVT::Other, CPIdx, CurDAG->getEntryNode()); @@ -204,12 +202,12 @@ replaceInChain(SelectionDAG *CurDAG, SDValue Chain, SDValue Old, SDValue New) } if (!found) return SDValue(); - return CurDAG->getNode(ISD::TokenFactor, Chain->getDebugLoc(), MVT::Other, + return CurDAG->getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, &Ops[0], Ops.size()); } SDNode *XCoreDAGToDAGISel::SelectBRIND(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); // (brind (int_xcore_checkevent (addr))) SDValue Chain = N->getOperand(0); SDValue Addr = N->getOperand(1); diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 2d27f1a0f6e38..89ad27daec133 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -59,6 +59,7 @@ getTargetNodeName(unsigned Opcode) const case XCoreISD::CRC8 : return "XCoreISD::CRC8"; case XCoreISD::BR_JT : return "XCoreISD::BR_JT"; case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32"; + case XCoreISD::MEMBARRIER : return "XCoreISD::MEMBARRIER"; default : return NULL; } } @@ -79,7 +80,7 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) setStackPointerRegisterToSaveRestore(XCore::SP); - setSchedulingPreference(Sched::RegPressure); + setSchedulingPreference(Sched::Source); // Use i32 for setcc operations results (slt, sgt, ...). setBooleanContents(ZeroOrOneBooleanContent); @@ -148,6 +149,13 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); + // Exception handling + setExceptionPointerRegister(XCore::R0); + setExceptionSelectorRegister(XCore::R1); + + // Atomic operations + setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); + // TRAMPOLINE is custom lowered. setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom); setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom); @@ -166,6 +174,24 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) setMinFunctionAlignment(1); } +bool XCoreTargetLowering::isZExtFree(SDValue Val, EVT VT2) const { + if (Val.getOpcode() != ISD::LOAD) + return false; + + EVT VT1 = Val.getValueType(); + if (!VT1.isSimple() || !VT1.isInteger() || + !VT2.isSimple() || !VT2.isInteger()) + return false; + + switch (VT1.getSimpleVT().SimpleTy) { + default: break; + case MVT::i8: + return true; + } + + return false; +} + SDValue XCoreTargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) @@ -188,6 +214,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG); case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); + case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG); default: llvm_unreachable("unimplemented operand"); } @@ -215,7 +242,7 @@ void XCoreTargetLowering::ReplaceNodeResults(SDNode *N, SDValue XCoreTargetLowering:: LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); SDValue Cond = DAG.getNode(ISD::SETCC, dl, MVT::i32, Op.getOperand(2), Op.getOperand(3), Op.getOperand(4)); return DAG.getNode(ISD::SELECT, dl, MVT::i32, Cond, Op.getOperand(0), @@ -227,7 +254,7 @@ getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, SelectionDAG &DAG) const { // FIXME there is no actual debug info here - DebugLoc dl = GA.getDebugLoc(); + SDLoc dl(GA); const GlobalValue *UnderlyingGV = GV; // If GV is an alias then use the aliasee to determine the wrapper type if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) @@ -243,7 +270,7 @@ getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, SDValue XCoreTargetLowering:: LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op); const GlobalValue *GV = GN->getGlobal(); int64_t Offset = GN->getOffset(); @@ -259,15 +286,10 @@ LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const return GA; } -static inline SDValue BuildGetId(SelectionDAG &DAG, DebugLoc dl) { - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, MVT::i32, - DAG.getConstant(Intrinsic::xcore_getid, MVT::i32)); -} - SDValue XCoreTargetLowering:: LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy()); @@ -280,7 +302,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); // FIXME there isn't really debug info here - DebugLoc dl = CP->getDebugLoc(); + SDLoc dl(CP); EVT PtrVT = Op.getValueType(); SDValue Res; if (CP->isMachineConstantPoolEntry()) { @@ -303,7 +325,7 @@ LowerBR_JT(SDValue Op, SelectionDAG &DAG) const SDValue Chain = Op.getOperand(0); SDValue Table = Op.getOperand(1); SDValue Index = Op.getOperand(2); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); JumpTableSDNode *JT = cast<JumpTableSDNode>(Table); unsigned JTI = JT->getIndex(); MachineFunction &MF = DAG.getMachineFunction(); @@ -322,7 +344,7 @@ LowerBR_JT(SDValue Op, SelectionDAG &DAG) const } SDValue XCoreTargetLowering:: -lowerLoadWordFromAlignedBasePlusOffset(DebugLoc DL, SDValue Chain, SDValue Base, +lowerLoadWordFromAlignedBasePlusOffset(SDLoc DL, SDValue Chain, SDValue Base, int64_t Offset, SelectionDAG &DAG) const { if ((Offset & 0x3) == 0) { @@ -388,7 +410,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = LD->getChain(); SDValue BasePtr = LD->getBasePtr(); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); if (!LD->isVolatile()) { const GlobalValue *GV; @@ -469,7 +491,7 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG) const SDValue Chain = ST->getChain(); SDValue BasePtr = ST->getBasePtr(); SDValue Value = ST->getValue(); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); if (ST->getAlignment() == 2) { SDValue Low = Value; @@ -516,7 +538,7 @@ LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const { assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::SMUL_LOHI && "Unexpected operand to lower!"); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); SDValue LHS = Op.getOperand(0); SDValue RHS = Op.getOperand(1); SDValue Zero = DAG.getConstant(0, MVT::i32); @@ -533,7 +555,7 @@ LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const { assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::UMUL_LOHI && "Unexpected operand to lower!"); - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); SDValue LHS = Op.getOperand(0); SDValue RHS = Op.getOperand(1); SDValue Zero = DAG.getConstant(0, MVT::i32); @@ -618,7 +640,7 @@ TryExpandADDWithMul(SDNode *N, SelectionDAG &DAG) const } else { return SDValue(); } - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); SDValue LL, RL, AddendL, AddendH; LL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Mul.getOperand(0), DAG.getConstant(0, MVT::i32)); @@ -677,7 +699,7 @@ ExpandADDSUB(SDNode *N, SelectionDAG &DAG) const return Result; } - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); // Extract components SDValue LHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, @@ -707,31 +729,33 @@ ExpandADDSUB(SDNode *N, SelectionDAG &DAG) const SDValue XCoreTargetLowering:: LowerVAARG(SDValue Op, SelectionDAG &DAG) const { - llvm_unreachable("unimplemented"); - // FIXME Arguments passed by reference need a extra dereference. + // Whist llvm does not support aggregate varargs we can ignore + // the possibility of the ValueType being an implicit byVal vararg. SDNode *Node = Op.getNode(); - DebugLoc dl = Node->getDebugLoc(); - const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); - EVT VT = Node->getValueType(0); - SDValue VAList = DAG.getLoad(getPointerTy(), dl, Node->getOperand(0), - Node->getOperand(1), MachinePointerInfo(V), + EVT VT = Node->getValueType(0); // not an aggregate + SDValue InChain = Node->getOperand(0); + SDValue VAListPtr = Node->getOperand(1); + EVT PtrVT = VAListPtr.getValueType(); + const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); + SDLoc dl(Node); + SDValue VAList = DAG.getLoad(PtrVT, dl, InChain, + VAListPtr, MachinePointerInfo(SV), false, false, false, 0); // Increment the pointer, VAList, to the next vararg - SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList, - DAG.getConstant(VT.getSizeInBits(), - getPointerTy())); + SDValue nextPtr = DAG.getNode(ISD::ADD, dl, PtrVT, VAList, + DAG.getIntPtrConstant(VT.getSizeInBits() / 8)); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), - MachinePointerInfo(V), false, false, 0); + InChain = DAG.getStore(VAList.getValue(1), dl, nextPtr, VAListPtr, + MachinePointerInfo(SV), false, false, 0); // Load the actual argument out of the pointer VAList - return DAG.getLoad(VT, dl, Tmp3, VAList, MachinePointerInfo(), + return DAG.getLoad(VT, dl, InChain, VAList, MachinePointerInfo(), false, false, false, 0); } SDValue XCoreTargetLowering:: LowerVASTART(SDValue Op, SelectionDAG &DAG) const { - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); // vastart stores the address of the VarArgsFrameIndex slot into the // memory location argument MachineFunction &MF = DAG.getMachineFunction(); @@ -743,7 +767,7 @@ LowerVASTART(SDValue Op, SelectionDAG &DAG) const SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); // Depths > 0 not supported yet! if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0) return SDValue(); @@ -783,7 +807,7 @@ LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { SDValue Addr = Trmp; - DebugLoc dl = Op.getDebugLoc(); + SDLoc dl(Op); OutChains[0] = DAG.getStore(Chain, dl, DAG.getConstant(0x0a3cd805, MVT::i32), Addr, MachinePointerInfo(TrmpAddr), false, false, 0); @@ -817,7 +841,7 @@ LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { SDValue XCoreTargetLowering:: LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); switch (IntNo) { case Intrinsic::xcore_crc8: @@ -832,6 +856,12 @@ LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const { return SDValue(); } +SDValue XCoreTargetLowering:: +LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const { + SDLoc DL(Op); + return DAG.getNode(XCoreISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0)); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// @@ -847,10 +877,10 @@ SDValue XCoreTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const { SelectionDAG &DAG = CLI.DAG; - DebugLoc &dl = CLI.DL; - SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; - SmallVector<SDValue, 32> &OutVals = CLI.OutVals; - SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; + SDLoc &dl = CLI.DL; + SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; + SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; + SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; SDValue Chain = CLI.Chain; SDValue Callee = CLI.Callee; bool &isTailCall = CLI.IsTailCall; @@ -883,7 +913,7 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { // Analyze operands of the call, assigning locations to each operand. @@ -901,7 +931,7 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, unsigned NumBytes = CCInfo.getNextStackOffset(); Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, - getPointerTy(), true)); + getPointerTy(), true), dl); SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; SmallVector<SDValue, 12> MemOpChains; @@ -991,7 +1021,7 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, getPointerTy(), true), DAG.getConstant(0, getPointerTy(), true), - InFlag); + InFlag, dl); InFlag = Chain.getValue(1); // Handle result values, copying them out of physregs into vregs that we @@ -1006,7 +1036,7 @@ SDValue XCoreTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { // Assign locations to each value returned by this call. @@ -1031,13 +1061,17 @@ XCoreTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, // Formal Arguments Calling Convention Implementation //===----------------------------------------------------------------------===// +namespace { + struct ArgDataPair { SDValue SDV; ISD::ArgFlagsTy Flags; }; +} + /// XCore formal arguments implementation SDValue XCoreTargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { @@ -1062,7 +1096,7 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); @@ -1080,9 +1114,22 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, unsigned LRSaveSize = StackSlotSize; + // All getCopyFromReg ops must precede any getMemcpys to prevent the + // scheduler clobbering a register before it has been copied. + // The stages are: + // 1. CopyFromReg (and load) arg & vararg registers. + // 2. Chain CopyFromReg nodes into a TokenFactor. + // 3. Memcpy 'byVal' args & push final InVals. + // 4. Chain mem ops nodes into a TokenFactor. + SmallVector<SDValue, 4> CFRegNode; + SmallVector<ArgDataPair, 4> ArgData; + SmallVector<SDValue, 4> MemOps; + + // 1a. CopyFromReg (and load) arg registers. for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; + SDValue ArgIn; if (VA.isRegLoc()) { // Arguments passed in registers @@ -1099,7 +1146,8 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, case MVT::i32: unsigned VReg = RegInfo.createVirtualRegister(&XCore::GRRegsRegClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); - InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT)); + ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); + CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1)); } } else { // sanity check @@ -1119,14 +1167,17 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); - InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, - MachinePointerInfo::getFixedStack(FI), - false, false, false, 0)); + ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, + MachinePointerInfo::getFixedStack(FI), + false, false, false, 0); } + const ArgDataPair ADP = { ArgIn, Ins[i].Flags }; + ArgData.push_back(ADP); } + // 1b. CopyFromReg vararg registers. if (isVarArg) { - /* Argument registers */ + // Argument registers static const uint16_t ArgRegs[] = { XCore::R0, XCore::R1, XCore::R2, XCore::R3 }; @@ -1134,7 +1185,6 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs, array_lengthof(ArgRegs)); if (FirstVAReg < array_lengthof(ArgRegs)) { - SmallVector<SDValue, 4> MemOps; int offset = 0; // Save remaining registers, storing higher register numbers at a higher // address @@ -1150,14 +1200,12 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, unsigned VReg = RegInfo.createVirtualRegister(&XCore::GRRegsRegClass); RegInfo.addLiveIn(ArgRegs[i], VReg); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); + CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1)); // Move argument from virt reg -> stack SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, MachinePointerInfo(), false, false, 0); MemOps.push_back(Store); } - if (!MemOps.empty()) - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &MemOps[0], MemOps.size()); } else { // This will point to the next argument passed via stack. XFI->setVarArgsFrameIndex( @@ -1166,6 +1214,42 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, } } + // 2. chain CopyFromReg nodes into a TokenFactor. + if (!CFRegNode.empty()) + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &CFRegNode[0], + CFRegNode.size()); + + // 3. Memcpy 'byVal' args & push final InVals. + // Aggregates passed "byVal" need to be copied by the callee. + // The callee will use a pointer to this copy, rather than the original + // pointer. + for (SmallVectorImpl<ArgDataPair>::const_iterator ArgDI = ArgData.begin(), + ArgDE = ArgData.end(); + ArgDI != ArgDE; ++ArgDI) { + if (ArgDI->Flags.isByVal() && ArgDI->Flags.getByValSize()) { + unsigned Size = ArgDI->Flags.getByValSize(); + unsigned Align = std::max(StackSlotSize, ArgDI->Flags.getByValAlign()); + // Create a new object on the stack and copy the pointee into it. + int FI = MFI->CreateStackObject(Size, Align, false, false); + SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); + InVals.push_back(FIN); + MemOps.push_back(DAG.getMemcpy(Chain, dl, FIN, ArgDI->SDV, + DAG.getConstant(Size, MVT::i32), + Align, false, false, + MachinePointerInfo(), + MachinePointerInfo())); + } else { + InVals.push_back(ArgDI->SDV); + } + } + + // 4, chain mem ops nodes into a TokenFactor. + if (!MemOps.empty()) { + MemOps.push_back(Chain); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &MemOps[0], + MemOps.size()); + } + return Chain; } @@ -1188,7 +1272,7 @@ XCoreTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const { + SDLoc dl, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of // the return value to a location @@ -1305,7 +1389,7 @@ XCoreTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { SelectionDAG &DAG = DCI.DAG; - DebugLoc dl = N->getDebugLoc(); + SDLoc dl(N); switch (N->getOpcode()) { default: break; case XCoreISD::LADD: { @@ -1582,7 +1666,7 @@ XCoreTargetLowering::isLegalAddressingMode(const AddrMode &AM, std::pair<unsigned, const TargetRegisterClass*> XCoreTargetLowering:: getRegForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const { + MVT VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { default : break; diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h index c7dfa2600691c..bc08497b12ed7 100644 --- a/lib/Target/XCore/XCoreISelLowering.h +++ b/lib/Target/XCore/XCoreISelLowering.h @@ -70,7 +70,10 @@ namespace llvm { BR_JT, // Jumptable branch using long branches for each entry. - BR_JT32 + BR_JT32, + + // Memory barrier. + MEMBARRIER }; } @@ -83,6 +86,10 @@ namespace llvm { explicit XCoreTargetLowering(XCoreTargetMachine &TM); + using TargetLowering::isZExtFree; + virtual bool isZExtFree(SDValue Val, EVT VT2) const; + + virtual unsigned getJumpTableEncoding() const; virtual MVT getScalarShiftAmountTy(EVT LHSTy) const { return MVT::i32; } @@ -115,7 +122,7 @@ namespace llvm { CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg, @@ -123,17 +130,17 @@ namespace llvm { const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; SDValue LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const; SDValue getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, SelectionDAG &DAG) const; - SDValue lowerLoadWordFromAlignedBasePlusOffset(DebugLoc DL, SDValue Chain, + SDValue lowerLoadWordFromAlignedBasePlusOffset(SDLoc DL, SDValue Chain, SDValue Base, int64_t Offset, SelectionDAG &DAG) const; @@ -154,11 +161,12 @@ namespace llvm { SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; // Inline asm support std::pair<unsigned, const TargetRegisterClass*> getRegForInlineAsmConstraint(const std::string &Constraint, - EVT VT) const; + MVT VT) const; // Expand specifics SDValue TryExpandADDWithMul(SDNode *Op, SelectionDAG &DAG) const; @@ -177,7 +185,7 @@ namespace llvm { CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; virtual SDValue @@ -189,7 +197,7 @@ namespace llvm { CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const; + SDLoc dl, SelectionDAG &DAG) const; virtual bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, diff --git a/lib/Target/XCore/XCoreInstrInfo.cpp b/lib/Target/XCore/XCoreInstrInfo.cpp index e457e0dbf0278..33c7f31be7613 100644 --- a/lib/Target/XCore/XCoreInstrInfo.cpp +++ b/lib/Target/XCore/XCoreInstrInfo.cpp @@ -22,7 +22,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" -#define GET_INSTRINFO_CTOR +#define GET_INSTRINFO_CTOR_DTOR #include "XCoreGenInstrInfo.inc" namespace llvm { @@ -39,9 +39,13 @@ namespace XCore { using namespace llvm; + +// Pin the vtable to this file. +void XCoreInstrInfo::anchor() {} + XCoreInstrInfo::XCoreInstrInfo() : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), - RI(*this) { + RI() { } static bool isZeroImm(const MachineOperand &op) { @@ -386,15 +390,6 @@ void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, .addImm(0); } -MachineInstr* -XCoreInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, - uint64_t Offset, const MDNode *MDPtr, - DebugLoc DL) const { - MachineInstrBuilder MIB = BuildMI(MF, DL, get(XCore::DBG_VALUE)) - .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr); - return &*MIB; -} - /// ReverseBranchCondition - Return the inverse opcode of the /// specified Branch instruction. bool XCoreInstrInfo:: diff --git a/lib/Target/XCore/XCoreInstrInfo.h b/lib/Target/XCore/XCoreInstrInfo.h index 42eeed8370f43..4429b07e41ed5 100644 --- a/lib/Target/XCore/XCoreInstrInfo.h +++ b/lib/Target/XCore/XCoreInstrInfo.h @@ -24,6 +24,7 @@ namespace llvm { class XCoreInstrInfo : public XCoreGenInstrInfo { const XCoreRegisterInfo RI; + virtual void anchor(); public: XCoreInstrInfo(); @@ -78,12 +79,6 @@ public: const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const; - virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, - int FrameIx, - uint64_t Offset, - const MDNode *MDPtr, - DebugLoc DL) const; - virtual bool ReverseBranchCondition( SmallVectorImpl<MachineOperand> &Cond) const; }; diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td index 587166c1ce1d1..934a707e785b9 100644 --- a/lib/Target/XCore/XCoreInstrInfo.td +++ b/lib/Target/XCore/XCoreInstrInfo.td @@ -70,6 +70,11 @@ def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart, def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; +def SDT_XCoreMEMBARRIER : SDTypeProfile<0, 0, []>; + +def XCoreMemBarrier : SDNode<"XCoreISD::MEMBARRIER", SDT_XCoreMEMBARRIER, + [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // Instruction Pattern Stuff //===----------------------------------------------------------------------===// @@ -84,7 +89,7 @@ def msksize_xform : SDNodeXForm<imm, [{ // Transformation function: get the size of a mask assert(isMask_32(N->getZExtValue())); // look for the first non-zero bit - return getI32Imm(32 - CountLeadingZeros_32(N->getZExtValue())); + return getI32Imm(32 - countLeadingZeros((uint32_t)N->getZExtValue())); }]>; def neg_xform : SDNodeXForm<imm, [{ @@ -279,12 +284,6 @@ multiclass FRU6_LRU6_backwards_branch<bits<6> opc, string OpcStr> { !strconcat(OpcStr, " $a, $b"), []>; } -multiclass FRU6_LRU6_cp<bits<6> opc, string OpcStr> { - def _ru6: _FRU6<opc, (outs RRegs:$a), (ins i32imm:$b), - !strconcat(OpcStr, " $a, cp[$b]"), []>; - def _lru6: _FLRU6<opc, (outs RRegs:$a), (ins i32imm:$b), - !strconcat(OpcStr, " $a, cp[$b]"), []>; -} // U6 multiclass FU6_LU6<bits<10> opc, string OpcStr, SDNode OpNode> { @@ -349,6 +348,10 @@ let usesCustomInserter = 1 in { (select GRRegs:$cond, GRRegs:$T, GRRegs:$F))]>; } +let hasSideEffects = 1 in +def Int_MemBarrier : PseudoInstXCore<(outs), (ins), "#MEMBARRIER", + [(XCoreMemBarrier)]>; + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -539,8 +542,13 @@ def STWDP_lru6 : _FLRU6<0b010100, (outs), (ins RRegs:$a, i32imm:$b), [(store RRegs:$a, (dprelwrapper tglobaladdr:$b))]>; //let Uses = [CP] in .. -let mayLoad = 1, isReMaterializable = 1, neverHasSideEffects = 1 in -defm LDWCP : FRU6_LRU6_cp<0b011011, "ldw">; +let mayLoad = 1, isReMaterializable = 1, neverHasSideEffects = 1 in { +def LDWCP_ru6 : _FRU6<0b011011, (outs RRegs:$a), (ins i32imm:$b), + "ldw $a, cp[$b]", []>; +def LDWCP_lru6: _FLRU6<0b011011, (outs RRegs:$a), (ins i32imm:$b), + "ldw $a, cp[$b]", + [(set RRegs:$a, (load (cprelwrapper tglobaladdr:$b)))]>; +} let Uses = [SP] in { let mayStore=1 in { diff --git a/lib/Target/XCore/XCoreLowerThreadLocal.cpp b/lib/Target/XCore/XCoreLowerThreadLocal.cpp index 2e328b4e3441a..afce753dec5c9 100644 --- a/lib/Target/XCore/XCoreLowerThreadLocal.cpp +++ b/lib/Target/XCore/XCoreLowerThreadLocal.cpp @@ -22,6 +22,9 @@ #include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/NoFolder.h" +#include "llvm/Support/ValueHandle.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" #define DEBUG_TYPE "xcore-lower-thread-local" @@ -71,13 +74,104 @@ createLoweredInitializer(ArrayType *NewType, Constant *OriginalInitializer) { return ConstantArray::get(NewType, Elements); } -static bool hasNonInstructionUse(GlobalVariable *GV) { - for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); UI != E; - ++UI) - if (!isa<Instruction>(*UI)) - return true; +static Instruction * +createReplacementInstr(ConstantExpr *CE, Instruction *Instr) { + IRBuilder<true,NoFolder> Builder(Instr); + unsigned OpCode = CE->getOpcode(); + switch (OpCode) { + case Instruction::GetElementPtr: { + SmallVector<Value *,4> CEOpVec(CE->op_begin(), CE->op_end()); + ArrayRef<Value *> CEOps(CEOpVec); + return dyn_cast<Instruction>(Builder.CreateInBoundsGEP(CEOps[0], + CEOps.slice(1))); + } + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: + case Instruction::UDiv: + case Instruction::SDiv: + case Instruction::FDiv: + case Instruction::URem: + case Instruction::SRem: + case Instruction::FRem: + case Instruction::Shl: + case Instruction::LShr: + case Instruction::AShr: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + return dyn_cast<Instruction>( + Builder.CreateBinOp((Instruction::BinaryOps)OpCode, + CE->getOperand(0), CE->getOperand(1), + CE->getName())); + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + return dyn_cast<Instruction>( + Builder.CreateCast((Instruction::CastOps)OpCode, + CE->getOperand(0), CE->getType(), + CE->getName())); + default: + llvm_unreachable("Unhandled constant expression!\n"); + } +} + +static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P) { + do { + SmallVector<WeakVH,8> WUsers; + for (Value::use_iterator I = CE->use_begin(), E = CE->use_end(); + I != E; ++I) + WUsers.push_back(WeakVH(*I)); + std::sort(WUsers.begin(), WUsers.end()); + WUsers.erase(std::unique(WUsers.begin(), WUsers.end()), WUsers.end()); + while (!WUsers.empty()) + if (WeakVH WU = WUsers.pop_back_val()) { + if (PHINode *PN = dyn_cast<PHINode>(WU)) { + for (int I = 0, E = PN->getNumIncomingValues(); I < E; ++I) + if (PN->getIncomingValue(I) == CE) { + BasicBlock *PredBB = PN->getIncomingBlock(I); + if (PredBB->getTerminator()->getNumSuccessors() > 1) + PredBB = SplitEdge(PredBB, PN->getParent(), P); + Instruction *InsertPos = PredBB->getTerminator(); + Instruction *NewInst = createReplacementInstr(CE, InsertPos); + PN->setOperand(I, NewInst); + } + } else if (Instruction *Instr = dyn_cast<Instruction>(WU)) { + Instruction *NewInst = createReplacementInstr(CE, Instr); + Instr->replaceUsesOfWith(CE, NewInst); + } else { + ConstantExpr *CExpr = dyn_cast<ConstantExpr>(WU); + if (!CExpr || !replaceConstantExprOp(CExpr, P)) + return false; + } + } + } while (CE->hasNUsesOrMore(1)); // We need to check becasue a recursive + // sibbling may have used 'CE' when createReplacementInstr was called. + CE->destroyConstant(); + return true; +} - return false; +static bool rewriteNonInstructionUses(GlobalVariable *GV, Pass *P) { + SmallVector<WeakVH,8> WUsers; + for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E; ++I) + if (!isa<Instruction>(*I)) + WUsers.push_back(WeakVH(*I)); + while (!WUsers.empty()) + if (WeakVH WU = WUsers.pop_back_val()) { + ConstantExpr *CE = dyn_cast<ConstantExpr>(WU); + if (!CE || !replaceConstantExprOp(CE, P)) + return false; + } + return true; } static bool isZeroLengthArray(Type *Ty) { @@ -92,14 +186,16 @@ bool XCoreLowerThreadLocal::lowerGlobal(GlobalVariable *GV) { return false; // Skip globals that we can't lower and leave it for the backend to error. - if (hasNonInstructionUse(GV) || + if (!rewriteNonInstructionUses(GV, this) || !GV->getType()->isSized() || isZeroLengthArray(GV->getType())) return false; // Create replacement global. ArrayType *NewType = createLoweredType(GV->getType()->getElementType()); - Constant *NewInitializer = createLoweredInitializer(NewType, - GV->getInitializer()); + Constant *NewInitializer = 0; + if (GV->hasInitializer()) + NewInitializer = createLoweredInitializer(NewType, + GV->getInitializer()); GlobalVariable *NewGV = new GlobalVariable(*M, NewType, GV->isConstant(), GV->getLinkage(), NewInitializer, "", 0, GlobalVariable::NotThreadLocal, diff --git a/lib/Target/XCore/XCoreMCInstLower.cpp b/lib/Target/XCore/XCoreMCInstLower.cpp index f96eda9fcb9f8..def2673fa5655 100644 --- a/lib/Target/XCore/XCoreMCInstLower.cpp +++ b/lib/Target/XCore/XCoreMCInstLower.cpp @@ -43,7 +43,7 @@ MCOperand XCoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO, Symbol = MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: - Symbol = Mang->getSymbol(MO.getGlobal()); + Symbol = Printer.getSymbol(MO.getGlobal()); Offset += MO.getOffset(); break; case MachineOperand::MO_BlockAddress: diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp index 49b563497c0b0..dbd2f52a5b1ae 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.cpp +++ b/lib/Target/XCore/XCoreRegisterInfo.cpp @@ -37,8 +37,8 @@ using namespace llvm; -XCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii) - : XCoreGenRegisterInfo(XCore::LR), TII(tii) { +XCoreRegisterInfo::XCoreRegisterInfo() + : XCoreGenRegisterInfo(XCore::LR) { } // helper functions @@ -112,6 +112,7 @@ XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int FrameIndex = FrameOp.getIndex(); MachineFunction &MF = *MI.getParent()->getParent(); + const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); int StackSize = MF.getFrameInfo()->getStackSize(); @@ -249,6 +250,7 @@ loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, report_fatal_error("loadConstant value too big " + Twine(Value)); } int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; + const TargetInstrInfo &TII = *MBB.getParent()->getTarget().getInstrInfo(); BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value); } diff --git a/lib/Target/XCore/XCoreRegisterInfo.h b/lib/Target/XCore/XCoreRegisterInfo.h index 1db32489cf8d1..2370c6280f2ed 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.h +++ b/lib/Target/XCore/XCoreRegisterInfo.h @@ -25,8 +25,6 @@ class TargetInstrInfo; struct XCoreRegisterInfo : public XCoreGenRegisterInfo { private: - const TargetInstrInfo &TII; - void loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DstReg, int64_t Value, DebugLoc dl) const; @@ -40,7 +38,7 @@ private: unsigned DstReg, int Offset, DebugLoc dl) const; public: - XCoreRegisterInfo(const TargetInstrInfo &tii); + XCoreRegisterInfo(); /// Code Generation virtual methods... diff --git a/lib/Target/XCore/XCoreTargetMachine.cpp b/lib/Target/XCore/XCoreTargetMachine.cpp index 07e5fff1413b6..9ae0b860dff91 100644 --- a/lib/Target/XCore/XCoreTargetMachine.cpp +++ b/lib/Target/XCore/XCoreTargetMachine.cpp @@ -33,6 +33,7 @@ XCoreTargetMachine::XCoreTargetMachine(const Target &T, StringRef TT, FrameLowering(Subtarget), TLInfo(*this), TSInfo(*this) { + initAsmInfo(); } namespace { @@ -69,3 +70,11 @@ bool XCorePassConfig::addInstSelector() { extern "C" void LLVMInitializeXCoreTarget() { RegisterTargetMachine<XCoreTargetMachine> X(TheXCoreTarget); } + +void XCoreTargetMachine::addAnalysisPasses(PassManagerBase &PM) { + // Add first the target-independent BasicTTI pass, then our XCore pass. This + // allows the XCore pass to delegate to the target independent layer when + // appropriate. + PM.add(createBasicTargetTransformInfoPass(this)); + PM.add(createXCoreTargetTransformInfoPass(this)); +} diff --git a/lib/Target/XCore/XCoreTargetMachine.h b/lib/Target/XCore/XCoreTargetMachine.h index eb9a1aa420eb4..a19a67727f2c5 100644 --- a/lib/Target/XCore/XCoreTargetMachine.h +++ b/lib/Target/XCore/XCoreTargetMachine.h @@ -57,6 +57,8 @@ public: // Pass Pipeline Configuration virtual TargetPassConfig *createPassConfig(PassManagerBase &PM); + + virtual void addAnalysisPasses(PassManagerBase &PM); }; } // end namespace llvm diff --git a/lib/Target/XCore/XCoreTargetTransformInfo.cpp b/lib/Target/XCore/XCoreTargetTransformInfo.cpp new file mode 100644 index 0000000000000..cc165f70dc285 --- /dev/null +++ b/lib/Target/XCore/XCoreTargetTransformInfo.cpp @@ -0,0 +1,83 @@ +//===-- XCoreTargetTransformInfo.cpp - XCore specific TTI pass ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements a TargetTransformInfo analysis pass specific to the +/// XCore target machine. It uses the target's detailed information to provide +/// more precise answers to certain TTI queries, while letting the target +/// independent and default TTI implementations handle the rest. +/// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "xcoretti" +#include "XCore.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Support/Debug.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Target/CostTable.h" +using namespace llvm; + +// Declare the pass initialization routine locally as target-specific passes +// don't havve a target-wide initialization entry point, and so we rely on the +// pass constructor initialization. +namespace llvm { +void initializeXCoreTTIPass(PassRegistry &); +} + +namespace { + +class XCoreTTI : public ImmutablePass, public TargetTransformInfo { +public: + XCoreTTI() : ImmutablePass(ID) { + llvm_unreachable("This pass cannot be directly constructed"); + } + + XCoreTTI(const XCoreTargetMachine *TM) + : ImmutablePass(ID) { + initializeXCoreTTIPass(*PassRegistry::getPassRegistry()); + } + + virtual void initializePass() { + pushTTIStack(this); + } + + virtual void finalizePass() { + popTTIStack(); + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + TargetTransformInfo::getAnalysisUsage(AU); + } + + static char ID; + + virtual void *getAdjustedAnalysisPointer(const void *ID) { + if (ID == &TargetTransformInfo::ID) + return (TargetTransformInfo*)this; + return this; + } + + unsigned getNumberOfRegisters(bool Vector) const { + if (Vector) { + return 0; + } + return 12; + } +}; + +} // end anonymous namespace + +INITIALIZE_AG_PASS(XCoreTTI, TargetTransformInfo, "xcoretti", + "XCore Target Transform Info", true, true, false) +char XCoreTTI::ID = 0; + + +ImmutablePass * +llvm::createXCoreTargetTransformInfoPass(const XCoreTargetMachine *TM) { + return new XCoreTTI(TM); +} |
