mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-11 08:29:25 +00:00
Add an abstraction to handle patchpoint operands.
Hard-coded operand indices were scattered throughout lowering stages and layers. It was super bug prone. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195093 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -28,10 +28,47 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void StackMaps::recordStackMap(const MachineInstr &MI, uint32_t ID,
|
||||
MachineInstr::const_mop_iterator MOI,
|
||||
MachineInstr::const_mop_iterator MOE,
|
||||
bool recordResult) {
|
||||
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() &&
|
||||
!MI->getOperand(CheckStartIdx).isImplicit())
|
||||
++CheckStartIdx;
|
||||
|
||||
assert(getMetaIdx() == CheckStartIdx &&
|
||||
"Unexpected additonal definition in Patchpoint intrinsic.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const {
|
||||
if (!StartIdx)
|
||||
StartIdx = getVarIdx();
|
||||
|
||||
// Find the next scratch register (implicit def and early clobber)
|
||||
unsigned ScratchIdx = StartIdx, e = MI->getNumOperands();
|
||||
while (ScratchIdx < e &&
|
||||
!(MI->getOperand(ScratchIdx).isReg() &&
|
||||
MI->getOperand(ScratchIdx).isDef() &&
|
||||
MI->getOperand(ScratchIdx).isImplicit() &&
|
||||
MI->getOperand(ScratchIdx).isEarlyClobber()))
|
||||
++ScratchIdx;
|
||||
|
||||
assert(ScratchIdx != e && "No scratch register available");
|
||||
return ScratchIdx;
|
||||
}
|
||||
|
||||
void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint32_t ID,
|
||||
MachineInstr::const_mop_iterator MOI,
|
||||
MachineInstr::const_mop_iterator MOE,
|
||||
bool recordResult) {
|
||||
|
||||
MCContext &OutContext = AP.OutStreamer.getContext();
|
||||
MCSymbol *MILabel = OutContext.CreateTempSymbol();
|
||||
@@ -73,6 +110,49 @@ void StackMaps::recordStackMap(const MachineInstr &MI, uint32_t ID,
|
||||
CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, CallsiteLocs));
|
||||
}
|
||||
|
||||
static MachineInstr::const_mop_iterator
|
||||
getStackMapEndMOP(MachineInstr::const_mop_iterator MOI,
|
||||
MachineInstr::const_mop_iterator MOE) {
|
||||
for (; MOI != MOE; ++MOI)
|
||||
if (MOI->isRegMask() || (MOI->isReg() && MOI->isImplicit()))
|
||||
break;
|
||||
|
||||
return MOI;
|
||||
}
|
||||
|
||||
void StackMaps::recordStackMap(const MachineInstr &MI) {
|
||||
assert(MI.getOpcode() == TargetOpcode::STACKMAP && "exected stackmap");
|
||||
|
||||
int64_t ID = MI.getOperand(0).getImm();
|
||||
assert((int32_t)ID == ID && "Stack maps hold 32-bit IDs");
|
||||
recordStackMapOpers(MI, ID, llvm::next(MI.operands_begin(), 2),
|
||||
getStackMapEndMOP(MI.operands_begin(),
|
||||
MI.operands_end()));
|
||||
}
|
||||
|
||||
void StackMaps::recordPatchPoint(const MachineInstr &MI) {
|
||||
assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "exected stackmap");
|
||||
|
||||
PatchPointOpers opers(&MI);
|
||||
int64_t ID = opers.getMetaOper(PatchPointOpers::IDPos).getImm();
|
||||
assert((int32_t)ID == ID && "Stack maps hold 32-bit IDs");
|
||||
MachineInstr::const_mop_iterator MOI =
|
||||
llvm::next(MI.operands_begin(), opers.getStackMapStartIdx());
|
||||
recordStackMapOpers(MI, ID, MOI, getStackMapEndMOP(MOI, MI.operands_end()),
|
||||
opers.isAnyReg() && opers.hasDef());
|
||||
|
||||
#ifndef NDEBUG
|
||||
// verify anyregcc
|
||||
LocationVec &Locations = CSInfos.back().Locations;
|
||||
if (opers.isAnyReg()) {
|
||||
unsigned NArgs = opers.getMetaOper(PatchPointOpers::NArgPos).getImm();
|
||||
for (unsigned i = 0, e = (opers.hasDef() ? NArgs+1 : NArgs); i != e; ++i)
|
||||
assert(Locations[i].LocType == Location::Register &&
|
||||
"anyreg arg must be in reg.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// serializeToStackMapSection conceptually populates the following fields:
|
||||
///
|
||||
/// uint32 : Reserved (header)
|
||||
|
Reference in New Issue
Block a user