summaryrefslogtreecommitdiff
path: root/lib/CodeGen/StackMaps.cpp
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2013-12-14 23:06:19 +0000
committerJuergen Ributzka <juergen@apple.com>2013-12-14 23:06:19 +0000
commitbfee01979076e8efed975a8ab166beba19ea11f0 (patch)
treea027867629b2e7fc27c1665933bfd2991c95821b /lib/CodeGen/StackMaps.cpp
parent729e476834c3a7e8ba742010cc950acd3a04fa3d (diff)
downloadllvm-bfee01979076e8efed975a8ab166beba19ea11f0.tar.gz
llvm-bfee01979076e8efed975a8ab166beba19ea11f0.tar.bz2
llvm-bfee01979076e8efed975a8ab166beba19ea11f0.tar.xz
[Stackmap] Refactor operand parsing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197329 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/StackMaps.cpp')
-rw-r--r--lib/CodeGen/StackMaps.cpp165
1 files changed, 74 insertions, 91 deletions
diff --git a/lib/CodeGen/StackMaps.cpp b/lib/CodeGen/StackMaps.cpp
index 8f6972d60f..19abcfd36e 100644
--- a/lib/CodeGen/StackMaps.cpp
+++ b/lib/CodeGen/StackMaps.cpp
@@ -29,14 +29,13 @@
using namespace llvm;
-PatchPointOpers::PatchPointOpers(const MachineInstr *MI):
- MI(MI),
- HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
- !MI->getOperand(0).isImplicit()),
- IsAnyReg(MI->getOperand(getMetaIdx(CCPos)).getImm() == CallingConv::AnyReg) {
-
+PatchPointOpers::PatchPointOpers(const MachineInstr *MI)
+ : MI(MI),
+ HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
+ !MI->getOperand(0).isImplicit()),
+ IsAnyReg(MI->getOperand(getMetaIdx(CCPos)).getImm() == CallingConv::AnyReg)
+{
#ifndef NDEBUG
- {
unsigned CheckStartIdx = 0, e = MI->getNumOperands();
while (CheckStartIdx < e && MI->getOperand(CheckStartIdx).isReg() &&
MI->getOperand(CheckStartIdx).isDef() &&
@@ -45,7 +44,6 @@ PatchPointOpers::PatchPointOpers(const MachineInstr *MI):
assert(getMetaIdx() == CheckStartIdx &&
"Unexpected additonal definition in Patchpoint intrinsic.");
- }
#endif
}
@@ -66,61 +64,64 @@ unsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const {
return ScratchIdx;
}
-std::pair<StackMaps::Location, MachineInstr::const_mop_iterator>
+MachineInstr::const_mop_iterator
StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
- MachineInstr::const_mop_iterator MOE) const {
- const MachineOperand &MOP = *MOI;
- assert((!MOP.isReg() || !MOP.isImplicit()) &&
- "Implicit operands should not be processed.");
-
- if (MOP.isImm()) {
- // Verify anyregcc
- // [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
-
- switch (MOP.getImm()) {
- default: llvm_unreachable("Unrecognized operand type.");
- case StackMaps::DirectMemRefOp: {
- unsigned Size = AP.TM.getDataLayout()->getPointerSizeInBits();
- assert((Size % 8) == 0 && "Need pointer size in bytes.");
- Size /= 8;
- unsigned Reg = (++MOI)->getReg();
- int64_t Imm = (++MOI)->getImm();
- return std::make_pair(
- Location(StackMaps::Location::Direct, Size, Reg, Imm), ++MOI);
- }
- case StackMaps::IndirectMemRefOp: {
- int64_t Size = (++MOI)->getImm();
- assert(Size > 0 && "Need a valid size for indirect memory locations.");
- unsigned Reg = (++MOI)->getReg();
- int64_t Imm = (++MOI)->getImm();
- return std::make_pair(
- Location(StackMaps::Location::Indirect, Size, Reg, Imm), ++MOI);
- }
- case StackMaps::ConstantOp: {
- ++MOI;
- assert(MOI->isImm() && "Expected constant operand.");
- int64_t Imm = MOI->getImm();
- return std::make_pair(
- Location(Location::Constant, sizeof(int64_t), 0, Imm), ++MOI);
- }
+ MachineInstr::const_mop_iterator MOE,
+ LocationVec &Locs, LiveOutVec &LiveOuts) const {
+ if (MOI->isImm()) {
+ switch (MOI->getImm()) {
+ default: llvm_unreachable("Unrecognized operand type.");
+ case StackMaps::DirectMemRefOp: {
+ unsigned Size = AP.TM.getDataLayout()->getPointerSizeInBits();
+ assert((Size % 8) == 0 && "Need pointer size in bytes.");
+ Size /= 8;
+ unsigned Reg = (++MOI)->getReg();
+ int64_t Imm = (++MOI)->getImm();
+ Locs.push_back(Location(StackMaps::Location::Direct, Size, Reg, Imm));
+ break;
}
+ case StackMaps::IndirectMemRefOp: {
+ int64_t Size = (++MOI)->getImm();
+ assert(Size > 0 && "Need a valid size for indirect memory locations.");
+ unsigned Reg = (++MOI)->getReg();
+ int64_t Imm = (++MOI)->getImm();
+ Locs.push_back(Location(StackMaps::Location::Indirect, Size, Reg, Imm));
+ break;
+ }
+ case StackMaps::ConstantOp: {
+ ++MOI;
+ assert(MOI->isImm() && "Expected constant operand.");
+ int64_t Imm = MOI->getImm();
+ Locs.push_back(Location(Location::Constant, sizeof(int64_t), 0, Imm));
+ break;
+ }
+ }
+ return ++MOI;
+ }
+
+ // The physical register number will ultimately be encoded as a DWARF regno.
+ // The stack map also records the size of a spill slot that can hold the
+ // register content. (The runtime can track the actual size of the data type
+ // if it needs to.)
+ if (MOI->isReg()) {
+ // Skip implicit registers (this includes our scratch registers)
+ if (MOI->isImplicit())
+ return ++MOI;
+
+ assert(TargetRegisterInfo::isPhysicalRegister(MOI->getReg()) &&
+ "Virtreg operands should have been rewritten before now.");
+ const TargetRegisterClass *RC =
+ AP.TM.getRegisterInfo()->getMinimalPhysRegClass(MOI->getReg());
+ assert(!MOI->getSubReg() && "Physical subreg still around.");
+ Locs.push_back(
+ Location(Location::Register, RC->getSize(), MOI->getReg(), 0));
+ return ++MOI;
}
- if (MOP.isRegMask() || MOP.isRegLiveOut())
- return std::make_pair(Location(), ++MOI);
-
- // Otherwise this is a reg operand. The physical register number will
- // ultimately be encoded as a DWARF regno. The stack map also records the size
- // of a spill slot that can hold the register content. (The runtime can
- // track the actual size of the data type if it needs to.)
- assert(MOP.isReg() && "Expected register operand here.");
- assert(TargetRegisterInfo::isPhysicalRegister(MOP.getReg()) &&
- "Virtreg operands should have been rewritten before now.");
- const TargetRegisterClass *RC =
- AP.TM.getRegisterInfo()->getMinimalPhysRegClass(MOP.getReg());
- assert(!MOP.getSubReg() && "Physical subreg still around.");
- return std::make_pair(
- Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI);
+ if (MOI->isRegLiveOut())
+ LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut());
+
+ return ++MOI;
}
/// Go up the super-register chain until we hit a valid dwarf register number.
@@ -195,28 +196,23 @@ void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
LiveOutVec LiveOuts;
if (recordResult) {
- std::pair<Location, MachineInstr::const_mop_iterator> ParseResult =
- parseOperand(MI.operands_begin(), llvm::next(MI.operands_begin()));
-
- Location &Loc = ParseResult.first;
- assert(Loc.LocType == Location::Register &&
- "Stackmap return location must be a register.");
- Locations.push_back(Loc);
+ assert(PatchPointOpers(&MI).hasDef() && "Stackmap has no return value.");
+ parseOperand(MI.operands_begin(), llvm::next(MI.operands_begin()),
+ Locations, LiveOuts);
}
+ // Parse operands.
while (MOI != MOE) {
- Location Loc;
- tie(Loc, MOI) = parseOperand(MOI, MOE);
+ MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
+ }
- // Move large constants into the constant pool.
- if (Loc.LocType == Location::Constant && (Loc.Offset & ~0xFFFFFFFFULL)) {
- Loc.LocType = Location::ConstantIndex;
- Loc.Offset = ConstPool.getConstantIndex(Loc.Offset);
+ // Move large constants into the constant pool.
+ for (LocationVec::iterator I = Locations.begin(), E = Locations.end();
+ I != E; ++I) {
+ if (I->LocType == Location::Constant && (I->Offset & ~0xFFFFFFFFULL)) {
+ I->LocType = Location::ConstantIndex;
+ I->Offset = ConstPool.getConstantIndex(I->Offset);
}
-
- // Skip the register mask and register live-out mask
- if (Loc.LocType != Location::Unprocessed)
- Locations.push_back(Loc);
}
const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub(
@@ -224,28 +220,15 @@ void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
MCSymbolRefExpr::Create(AP.CurrentFnSym, OutContext),
OutContext);
- if (MOI->isRegLiveOut())
- LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut());
-
CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, Locations, LiveOuts));
}
-static MachineInstr::const_mop_iterator
-getStackMapEndMOP(MachineInstr::const_mop_iterator MOI,
- MachineInstr::const_mop_iterator MOE) {
- for (; MOI != MOE; ++MOI)
- if (MOI->isRegLiveOut() || (MOI->isReg() && MOI->isImplicit()))
- break;
- return MOI;
-}
-
void StackMaps::recordStackMap(const MachineInstr &MI) {
assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap");
int64_t ID = MI.getOperand(0).getImm();
recordStackMapOpers(MI, ID, llvm::next(MI.operands_begin(), 2),
- getStackMapEndMOP(MI.operands_begin(),
- MI.operands_end()));
+ MI.operands_end());
}
void StackMaps::recordPatchPoint(const MachineInstr &MI) {
@@ -256,7 +239,7 @@ void StackMaps::recordPatchPoint(const MachineInstr &MI) {
MachineInstr::const_mop_iterator MOI =
llvm::next(MI.operands_begin(), opers.getStackMapStartIdx());
- recordStackMapOpers(MI, ID, MOI, getStackMapEndMOP(MOI, MI.operands_end()),
+ recordStackMapOpers(MI, ID, MOI, MI.operands_end(),
opers.isAnyReg() && opers.hasDef());
#ifndef NDEBUG