aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/XCore
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-12-22 00:04:03 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-12-22 00:04:03 +0000
commitf8af5cf600354830d4ccf59732403f0f073eccb9 (patch)
tree2ba0398b4c42ad4f55561327538044fd2c925a8b /lib/Target/XCore
parent59d6cff90eecf31cb3dd860c4e786674cfdd42eb (diff)
Notes
Diffstat (limited to 'lib/Target/XCore')
-rw-r--r--lib/Target/XCore/CMakeLists.txt3
-rw-r--r--lib/Target/XCore/Disassembler/XCoreDisassembler.cpp8
-rw-r--r--lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.cpp10
-rw-r--r--lib/Target/XCore/MCTargetDesc/XCoreMCAsmInfo.h6
-rw-r--r--lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp10
-rw-r--r--lib/Target/XCore/README.txt1
-rw-r--r--lib/Target/XCore/XCore.h2
-rw-r--r--lib/Target/XCore/XCoreAsmPrinter.cpp80
-rw-r--r--lib/Target/XCore/XCoreFrameLowering.cpp107
-rw-r--r--lib/Target/XCore/XCoreISelDAGToDAG.cpp14
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp200
-rw-r--r--lib/Target/XCore/XCoreISelLowering.h24
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.cpp17
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.h7
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.td26
-rw-r--r--lib/Target/XCore/XCoreLowerThreadLocal.cpp114
-rw-r--r--lib/Target/XCore/XCoreMCInstLower.cpp2
-rw-r--r--lib/Target/XCore/XCoreRegisterInfo.cpp6
-rw-r--r--lib/Target/XCore/XCoreRegisterInfo.h4
-rw-r--r--lib/Target/XCore/XCoreTargetMachine.cpp9
-rw-r--r--lib/Target/XCore/XCoreTargetMachine.h2
-rw-r--r--lib/Target/XCore/XCoreTargetTransformInfo.cpp83
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 &region,
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 &region,
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);
+}