[llvm] r212140 - [FastISel] Factor out stackmap intrinsic selection code into a dedicated helper method. NFCI.
Juergen Ributzka
juergen at apple.com
Tue Jul 1 15:25:50 PDT 2014
Author: ributzka
Date: Tue Jul 1 17:25:49 2014
New Revision: 212140
URL: http://llvm.org/viewvc/llvm-project?rev=212140&view=rev
Log:
[FastISel] Factor out stackmap intrinsic selection code into a dedicated helper method. NFCI.
Modified:
llvm/trunk/include/llvm/CodeGen/FastISel.h
llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=212140&r1=212139&r2=212140&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Tue Jul 1 17:25:49 2014
@@ -387,6 +387,7 @@ private:
bool SelectGetElementPtr(const User *I);
+ bool SelectStackmap(const CallInst *I);
bool SelectCall(const User *I);
bool SelectBitCast(const User *I);
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=212140&r1=212139&r2=212140&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Tue Jul 1 17:25:49 2014
@@ -561,13 +561,13 @@ bool FastISel::SelectGetElementPtr(const
return true;
}
-/// \brief Add a stack map intrinsic call's live variable operands to a stackmap
-/// or patchpoint machine instruction.
-///
+/// \brief Add a stackmap or patchpoint intrinsic call's live variable operands
+/// to a stackmap or patchpoint machine instruction.
bool FastISel::addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,
const CallInst *CI, unsigned StartIdx) {
for (unsigned i = StartIdx, e = CI->getNumArgOperands(); i != e; ++i) {
Value *Val = CI->getArgOperand(i);
+ // Check for constants and encode them with a StackMaps::ConstantOp prefix.
if (auto *C = dyn_cast<ConstantInt>(Val)) {
Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp));
Ops.push_back(MachineOperand::CreateImm(C->getSExtValue()));
@@ -575,6 +575,9 @@ bool FastISel::addStackMapLiveVars(Small
Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp));
Ops.push_back(MachineOperand::CreateImm(0));
} else if (auto *AI = dyn_cast<AllocaInst>(Val)) {
+ // Values coming from a stack location also require a sepcial encoding,
+ // but that is added later on by the target specific frame index
+ // elimination implementation.
auto SI = FuncInfo.StaticAllocaMap.find(AI);
if (SI != FuncInfo.StaticAllocaMap.end())
Ops.push_back(MachineOperand::CreateFI(SI->second));
@@ -591,6 +594,74 @@ bool FastISel::addStackMapLiveVars(Small
return true;
}
+bool FastISel::SelectStackmap(const CallInst *I) {
+ // void @llvm.experimental.stackmap(i64 <id>, i32 <numShadowBytes>,
+ // [live variables...])
+ assert(I->getCalledFunction()->getReturnType()->isVoidTy() &&
+ "Stackmap cannot return a value.");
+
+ // The stackmap intrinsic only records the live variables (the arguments
+ // passed to it) and emits NOPS (if requested). Unlike the patchpoint
+ // intrinsic, this won't be lowered to a function call. This means we don't
+ // have to worry about calling conventions and target-specific lowering code.
+ // Instead we perform the call lowering right here.
+ //
+ // CALLSEQ_START(0)
+ // STACKMAP(id, nbytes, ...)
+ // CALLSEQ_END(0, 0)
+ //
+ SmallVector<MachineOperand, 32> Ops;
+
+ // Add the <id> and <numBytes> constants.
+ assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::IDPos)) &&
+ "Expected a constant integer.");
+ const auto *ID = cast<ConstantInt>(I->getOperand(PatchPointOpers::IDPos));
+ Ops.push_back(MachineOperand::CreateImm(ID->getZExtValue()));
+
+ assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos)) &&
+ "Expected a constant integer.");
+ const auto *NumBytes =
+ cast<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos));
+ Ops.push_back(MachineOperand::CreateImm(NumBytes->getZExtValue()));
+
+ // Push live variables for the stack map (skipping the first two arguments
+ // <id> and <numBytes>).
+ if (!addStackMapLiveVars(Ops, I, 2))
+ return false;
+
+ // We are not adding any register mask info here, because the stackmap doesn't
+ // clobber anything.
+
+ // Add scratch registers as implicit def and early clobber.
+ CallingConv::ID CC = I->getCallingConv();
+ const MCPhysReg *ScratchRegs = TLI.getScratchRegisters(CC);
+ for (unsigned i = 0; ScratchRegs[i]; ++i)
+ Ops.push_back(MachineOperand::CreateReg(
+ ScratchRegs[i], /*IsDef=*/true, /*IsImp=*/true, /*IsKill=*/false,
+ /*IsDead=*/false, /*IsUndef=*/false, /*IsEarlyClobber=*/true));
+
+ // Issue CALLSEQ_START
+ unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackDown))
+ .addImm(0);
+
+ // Issue STACKMAP.
+ MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
+ TII.get(TargetOpcode::STACKMAP));
+ for (auto const &MO : Ops)
+ MIB.addOperand(MO);
+
+ // Issue CALLSEQ_END
+ unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
+ BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackUp))
+ .addImm(0).addImm(0);
+
+ // Inform the Frame Information that we have a stackmap in this function.
+ FuncInfo.MF->getFrameInfo()->setHasStackMap();
+
+ return true;
+}
+
bool FastISel::SelectCall(const User *I) {
const CallInst *Call = cast<CallInst>(I);
@@ -746,76 +817,8 @@ bool FastISel::SelectCall(const User *I)
UpdateValueMap(Call, ResultReg);
return true;
}
- case Intrinsic::experimental_stackmap: {
- // void @llvm.experimental.stackmap(i64 <id>, i32 <numShadowBytes>,
- // [live variables...])
-
- assert(Call->getCalledFunction()->getReturnType()->isVoidTy() &&
- "Stackmap cannot return a value.");
-
- // The stackmap intrinsic only records the live variables (the arguments
- // passed to it) and emits NOPS (if requested). Unlike the patchpoint
- // intrinsic, this won't be lowered to a function call. This means we don't
- // have to worry about calling conventions and target-specific lowering
- // code. Instead we perform the call lowering right here.
- //
- // CALLSEQ_START(0)
- // STACKMAP(id, nbytes, ...)
- // CALLSEQ_END(0, 0)
- //
-
- SmallVector<MachineOperand, 32> Ops;
-
- // Add the <id> and <numBytes> constants.
- assert(isa<ConstantInt>(Call->getOperand(PatchPointOpers::IDPos)) &&
- "Expected a constant integer.");
- auto IDVal = cast<ConstantInt>(Call->getOperand(PatchPointOpers::IDPos));
- Ops.push_back(MachineOperand::CreateImm(IDVal->getZExtValue()));
-
- assert(isa<ConstantInt>(Call->getOperand(PatchPointOpers::NBytesPos)) &&
- "Expected a constant integer.");
- auto NBytesVal =
- cast<ConstantInt>(Call->getOperand(PatchPointOpers::NBytesPos));
- Ops.push_back(MachineOperand::CreateImm(NBytesVal->getZExtValue()));
-
- // Push live variables for the stack map.
- if (!addStackMapLiveVars(Ops, Call, 2))
- return false;
-
- // We are not adding any register mask info here, because the stackmap
- // doesn't clobber anything.
-
- // Add scratch registers as implicit def and early clobber.
- CallingConv::ID CC = Call->getCallingConv();
- const MCPhysReg *ScratchRegs = TLI.getScratchRegisters(CC);
- for (unsigned i = 0; ScratchRegs[i]; ++i)
- Ops.push_back(MachineOperand::CreateReg(
- ScratchRegs[i], /*IsDef=*/true, /*IsImp=*/true, /*IsKill=*/false,
- /*IsDead=*/false, /*IsUndef=*/false, /*IsEarlyClobber=*/true));
-
- // Issue CALLSEQ_START
- unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackDown))
- .addImm(0);
-
- // Issue STACKMAP.
- MachineInstrBuilder MIB;
- MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
- TII.get(TargetOpcode::STACKMAP));
-
- for (auto const &MO : Ops)
- MIB.addOperand(MO);
-
- // Issue CALLSEQ_END
- unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
- BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AdjStackUp))
- .addImm(0).addImm(0);
-
- // Inform the Frame Information that we have a stackmap in this function.
- FuncInfo.MF->getFrameInfo()->setHasStackMap();
-
- return true;
- }
+ case Intrinsic::experimental_stackmap:
+ return SelectStackmap(Call);
}
// Usually, it does not make sense to initialize a value,
More information about the llvm-commits
mailing list