From 190305b648e500ac4b9c55cdb16ec0d7cb6a6888 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Tue, 1 Jul 2014 22:25:49 +0000 Subject: [PATCH] [FastISel] Factor out stackmap intrinsic selection code into a dedicated helper method. NFCI. llvm-svn: 212140 --- llvm/include/llvm/CodeGen/FastISel.h | 1 + llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 149 +++++++++++++++-------------- 2 files changed, 77 insertions(+), 73 deletions(-) diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h index c7ec6a0..4469bd1 100644 --- a/llvm/include/llvm/CodeGen/FastISel.h +++ b/llvm/include/llvm/CodeGen/FastISel.h @@ -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); diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index f7da4d5..5db2545 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -561,13 +561,13 @@ bool FastISel::SelectGetElementPtr(const User *I) { 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 &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(Val)) { Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp)); Ops.push_back(MachineOperand::CreateImm(C->getSExtValue())); @@ -575,6 +575,9 @@ bool FastISel::addStackMapLiveVars(SmallVectorImpl &Ops, Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp)); Ops.push_back(MachineOperand::CreateImm(0)); } else if (auto *AI = dyn_cast(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(SmallVectorImpl &Ops, return true; } +bool FastISel::SelectStackmap(const CallInst *I) { + // void @llvm.experimental.stackmap(i64 , i32 , + // [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 Ops; + + // Add the and constants. + assert(isa(I->getOperand(PatchPointOpers::IDPos)) && + "Expected a constant integer."); + const auto *ID = cast(I->getOperand(PatchPointOpers::IDPos)); + Ops.push_back(MachineOperand::CreateImm(ID->getZExtValue())); + + assert(isa(I->getOperand(PatchPointOpers::NBytesPos)) && + "Expected a constant integer."); + const auto *NumBytes = + cast(I->getOperand(PatchPointOpers::NBytesPos)); + Ops.push_back(MachineOperand::CreateImm(NumBytes->getZExtValue())); + + // Push live variables for the stack map (skipping the first two arguments + // and ). + 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(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 , i32 , - // [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 Ops; - - // Add the and constants. - assert(isa(Call->getOperand(PatchPointOpers::IDPos)) && - "Expected a constant integer."); - auto IDVal = cast(Call->getOperand(PatchPointOpers::IDPos)); - Ops.push_back(MachineOperand::CreateImm(IDVal->getZExtValue())); - - assert(isa(Call->getOperand(PatchPointOpers::NBytesPos)) && - "Expected a constant integer."); - auto NBytesVal = - cast(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, -- 2.7.4