diff options
author | Andrew Trick <atrick@apple.com> | 2013-11-17 01:36:23 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2013-11-17 01:36:23 +0000 |
commit | bb756ca24401e190e3b704e5d92759c7a79cc6b7 (patch) | |
tree | 0c4bcba47b3a9717739a7c8f876a88363dc3ae02 /lib/CodeGen | |
parent | b7dabccbce5fc6fcf7b36669eb04abcb001e7f9e (diff) | |
download | external_llvm-bb756ca24401e190e3b704e5d92759c7a79cc6b7.zip external_llvm-bb756ca24401e190e3b704e5d92759c7a79cc6b7.tar.gz external_llvm-bb756ca24401e190e3b704e5d92759c7a79cc6b7.tar.bz2 |
Added a size field to the stack map record to handle subregister spills.
Implementing this on bigendian platforms could get strange. I added a
target hook, getStackSlotRange, per Jakob's recommendation to make
this as explicit as possible.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194942 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/InlineSpiller.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/StackMaps.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/TargetInstrInfo.cpp | 31 |
3 files changed, 50 insertions, 6 deletions
diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 99d2bd4..bb0e642 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -1057,6 +1057,9 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr*, unsigned> > Ops, bool WasCopy = MI->isCopy(); unsigned ImpReg = 0; + bool SpillSubRegs = (MI->getOpcode() == TargetOpcode::PATCHPOINT || + MI->getOpcode() == TargetOpcode::STACKMAP); + // TargetInstrInfo::foldMemoryOperand only expects explicit, non-tied // operands. SmallVector<unsigned, 8> FoldOps; @@ -1068,7 +1071,7 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr*, unsigned> > Ops, continue; } // FIXME: Teach targets to deal with subregs. - if (MO.getSubReg()) + if (!SpillSubRegs && MO.getSubReg()) return false; // We cannot fold a load instruction into a def. if (LoadMI && MO.isDef()) diff --git a/lib/CodeGen/StackMaps.cpp b/lib/CodeGen/StackMaps.cpp index 89da782..0eeec83 100644 --- a/lib/CodeGen/StackMaps.cpp +++ b/lib/CodeGen/StackMaps.cpp @@ -41,7 +41,7 @@ void StackMaps::recordStackMap(const MachineInstr &MI, uint32_t ID, if (recordResult) { std::pair<Location, MachineInstr::const_mop_iterator> ParseResult = - OpParser(MI.operands_begin(), llvm::next(MI.operands_begin(), 1)); + OpParser(MI.operands_begin(), llvm::next(MI.operands_begin()), AP.TM); Location &Loc = ParseResult.first; assert(Loc.LocType == Location::Register && @@ -51,7 +51,7 @@ void StackMaps::recordStackMap(const MachineInstr &MI, uint32_t ID, while (MOI != MOE) { std::pair<Location, MachineInstr::const_mop_iterator> ParseResult = - OpParser(MOI, MOE); + OpParser(MOI, MOE, AP.TM); Location &Loc = ParseResult.first; @@ -86,7 +86,7 @@ void StackMaps::recordStackMap(const MachineInstr &MI, uint32_t ID, /// uint16 : NumLocations /// Location[NumLocations] { /// uint8 : Register | Direct | Indirect | Constant | ConstantIndex -/// uint8 : Reserved (location flags) +/// uint8 : Size in Bytes /// uint16 : Dwarf RegNum /// int32 : Offset /// } @@ -200,12 +200,22 @@ void StackMaps::serializeToStackMapSection() { ); unsigned RegNo = 0; + int Offset = Loc.Offset; if(Loc.Reg) { RegNo = MCRI.getDwarfRegNum(Loc.Reg, false); for (MCSuperRegIterator SR(Loc.Reg, TRI); SR.isValid() && (int)RegNo < 0; ++SR) { RegNo = TRI->getDwarfRegNum(*SR, false); } + // If this is a register location, put the subregister byte offset in + // the location offset. + if (Loc.LocType == Location::Register) { + assert(!Loc.Offset && "Register location should have zero offset"); + unsigned LLVMRegNo = MCRI.getLLVMRegNum(RegNo, false); + unsigned SubRegIdx = MCRI.getSubRegIndex(LLVMRegNo, Loc.Reg); + if (SubRegIdx) + Offset = MCRI.getSubRegIdxOffset(SubRegIdx); + } } else { assert((Loc.LocType != Location::Register @@ -213,9 +223,9 @@ void StackMaps::serializeToStackMapSection() { "Missing location register"); } AP.OutStreamer.EmitIntValue(Loc.LocType, 1); - AP.OutStreamer.EmitIntValue(0, 1); // Reserved location flags. + AP.OutStreamer.EmitIntValue(Loc.Size, 1); AP.OutStreamer.EmitIntValue(RegNo, 2); - AP.OutStreamer.EmitIntValue(Loc.Offset, 4); + AP.OutStreamer.EmitIntValue(Offset, 4); } } diff --git a/lib/CodeGen/TargetInstrInfo.cpp b/lib/CodeGen/TargetInstrInfo.cpp index edeca3d..bf4fd65 100644 --- a/lib/CodeGen/TargetInstrInfo.cpp +++ b/lib/CodeGen/TargetInstrInfo.cpp @@ -17,6 +17,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/ScoreboardHazardRecognizer.h" +#include "llvm/IR/DataLayout.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Support/CommandLine.h" @@ -276,6 +277,36 @@ bool TargetInstrInfo::hasStoreToStackSlot(const MachineInstr *MI, return false; } +bool TargetInstrInfo::getStackSlotRange(const TargetRegisterClass *RC, + unsigned SubIdx, unsigned &Size, + unsigned &Offset, + const TargetMachine *TM) const { + if (!SubIdx) { + Size = RC->getSize(); + Offset = 0; + return true; + } + unsigned BitSize = TM->getRegisterInfo()->getSubRegIdxSize(SubIdx); + // Convert bit size to byte size to be consistent with + // MCRegisterClass::getSize(). + if (BitSize % 8) + return false; + + int BitOffset = TM->getRegisterInfo()->getSubRegIdxOffset(SubIdx); + if (BitOffset < 0 || BitOffset % 8) + return false; + + Size = BitSize /= 8; + Offset = (unsigned)BitOffset / 8; + + assert(RC->getSize() >= (Offset + Size) && "bad subregister range"); + + if (!TM->getDataLayout()->isLittleEndian()) { + Offset = RC->getSize() - (Offset + Size); + } + return true; +} + void TargetInstrInfo::reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, |