[llvm] r193769 - Lower stackmap intrinsics directly to their target opcode in the DAG builder.
Aaron Ballman
aaron at aaronballman.com
Fri Nov 1 08:09:24 PDT 2013
On Thu, Oct 31, 2013 at 1:18 PM, Andrew Trick <atrick at apple.com> wrote:
> Author: atrick
> Date: Thu Oct 31 12:18:24 2013
> New Revision: 193769
>
> URL: http://llvm.org/viewvc/llvm-project?rev=193769&view=rev
> Log:
> Lower stackmap intrinsics directly to their target opcode in the DAG builder.
>
> Modified:
> llvm/trunk/include/llvm/Target/Target.td
> llvm/trunk/include/llvm/Target/TargetLowering.h
> llvm/trunk/include/llvm/Target/TargetOpcodes.h
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
> llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
> llvm/trunk/utils/TableGen/CodeGenTarget.cpp
>
> Modified: llvm/trunk/include/llvm/Target/Target.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=193769&r1=193768&r2=193769&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/Target.td (original)
> +++ llvm/trunk/include/llvm/Target/Target.td Thu Oct 31 12:18:24 2013
> @@ -800,6 +800,19 @@ def LIFETIME_END : Instruction {
> let AsmString = "LIFETIME_END";
> let neverHasSideEffects = 1;
> }
> +def STACKMAP : Instruction {
> + let OutOperandList = (outs);
> + let InOperandList = (ins i32imm:$id, i32imm:$nbytes, variable_ops);
> + let isCall = 1;
> + let mayLoad = 1;
> +}
> +def PATCHPOINT : Instruction {
> + let OutOperandList = (outs);
> + let InOperandList = (ins i32imm:$id, i32imm:$nbytes, unknown:$callee,
> + i32imm:$nargs, variable_ops);
> + let isCall = 1;
> + let mayLoad = 1;
> +}
> }
>
> //===----------------------------------------------------------------------===//
>
> Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=193769&r1=193768&r2=193769&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
> +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Oct 31 12:18:24 2013
> @@ -1920,6 +1920,8 @@ public:
> ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
> isSRet(false), isNest(false), isByVal(false), isReturned(false),
> Alignment(0) { }
> +
> + void setAttributes(ImmutableCallSite *CS, unsigned AttrIdx);
> };
> typedef std::vector<ArgListEntry> ArgListTy;
>
>
> Modified: llvm/trunk/include/llvm/Target/TargetOpcodes.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOpcodes.h?rev=193769&r1=193768&r2=193769&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Target/TargetOpcodes.h (original)
> +++ llvm/trunk/include/llvm/Target/TargetOpcodes.h Thu Oct 31 12:18:24 2013
> @@ -92,7 +92,19 @@ namespace TargetOpcode {
>
> /// Lifetime markers.
> LIFETIME_START = 15,
> - LIFETIME_END = 16
> + LIFETIME_END = 16,
> +
> + /// A Stackmap instruction captures the location of live variables at its
> + /// position in the instruction stream. It is followed by a shadow of bytes
> + /// that must lie within the function and not contain another stackmap.
> + STACKMAP = 17,
> +
> + /// Patchable call instruction - this instruction represents a call to a
> + /// constant address, followed by a series of NOPs. It is intended to
> + /// support optimizations for dynamic languages (such as javascript) that
> + /// rewrite calls to runtimes with more efficient code sequences.
> + /// This also implies a stack map.
> + PATCHPOINT = 18
> };
> } // end namespace TargetOpcode
> } // end namespace llvm
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=193769&r1=193768&r2=193769&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Thu Oct 31 12:18:24 2013
> @@ -5309,6 +5309,15 @@ SelectionDAGBuilder::visitIntrinsicCall(
> case Intrinsic::donothing:
> // ignore
> return 0;
> + case Intrinsic::experimental_stackmap: {
> + visitStackmap(I);
> + return 0;
> + }
> + case Intrinsic::experimental_patchpoint_void:
> + case Intrinsic::experimental_patchpoint_i64: {
> + visitPatchpoint(I);
> + return 0;
> + }
> }
> }
>
> @@ -5373,15 +5382,8 @@ void SelectionDAGBuilder::LowerCallTo(Im
> SDValue ArgNode = getValue(V);
> Entry.Node = ArgNode; Entry.Ty = V->getType();
>
> - unsigned attrInd = i - CS.arg_begin() + 1;
> - Entry.isSExt = CS.paramHasAttr(attrInd, Attribute::SExt);
> - Entry.isZExt = CS.paramHasAttr(attrInd, Attribute::ZExt);
> - Entry.isInReg = CS.paramHasAttr(attrInd, Attribute::InReg);
> - Entry.isSRet = CS.paramHasAttr(attrInd, Attribute::StructRet);
> - Entry.isNest = CS.paramHasAttr(attrInd, Attribute::Nest);
> - Entry.isByVal = CS.paramHasAttr(attrInd, Attribute::ByVal);
> - Entry.isReturned = CS.paramHasAttr(attrInd, Attribute::Returned);
> - Entry.Alignment = CS.getParamAlignment(attrInd);
> + // Skip the first return-type Attribute to get to params.
> + Entry.setAttributes(&CS, i - CS.arg_begin() + 1);
> Args.push_back(Entry);
> }
>
> @@ -5463,8 +5465,8 @@ void SelectionDAGBuilder::LowerCallTo(Im
> }
>
> if (!Result.second.getNode()) {
> - // As a special case, a null chain means that a tail call has been emitted and
> - // the DAG root is already updated.
> + // As a special case, a null chain means that a tail call has been emitted
> + // and the DAG root is already updated.
> HasTailCall = true;
>
> // Since there's no actual continuation from this block, nothing can be
> @@ -6721,6 +6723,189 @@ void SelectionDAGBuilder::visitVACopy(co
> DAG.getSrcValue(I.getArgOperand(1))));
> }
>
> +/// \brief Lower an argument list according to the target calling convention.
> +///
> +/// \return A tuple of <return-value, token-chain>
> +///
> +/// This is a helper for lowering intrinsics that follow a target calling
> +/// convention or require stack pointer adjustment. Only a subset of the
> +/// intrinsic's operands need to participate in the calling convention.
> +std::pair<SDValue, SDValue>
> +SelectionDAGBuilder::LowerCallOperands(const CallInst &CI, unsigned ArgIdx,
> + unsigned NumArgs, SDValue Callee) {
> + TargetLowering::ArgListTy Args;
> + Args.reserve(NumArgs);
> +
> + // Populate the argument list.
> + // Attributes for args start at offset 1, after the return attribute.
> + ImmutableCallSite CS(&CI);
> + for (unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs, AttrI = ArgIdx + 1;
> + ArgI != ArgE; ++ArgI) {
> + const Value *V = CI.getOperand(ArgI);
> +
> + assert(!V->getType()->isEmptyTy() && "Empty type passed to intrinsic.");
> +
> + TargetLowering::ArgListEntry Entry;
> + Entry.Node = getValue(V);
> + Entry.Ty = V->getType();
> + Entry.setAttributes(&CS, AttrI);
> + Args.push_back(Entry);
> + }
> +
> + TargetLowering::CallLoweringInfo CLI(getRoot(), CI.getType(),
> + /*retSExt*/ false, /*retZExt*/ false, /*isVarArg*/ false, /*isInReg*/ false,
> + NumArgs, CI.getCallingConv(), /*isTailCall*/ false, /*doesNotReturn*/ false,
> + /*isReturnValueUsed*/ CI.use_empty(), Callee, Args, DAG, getCurSDLoc());
> +
> + const TargetLowering *TLI = TM.getTargetLowering();
> + return TLI->LowerCallTo(CLI);
> +}
> +
> +/// \brief Lower llvm.experimental.stackmap directly to its target opcode.
> +void SelectionDAGBuilder::visitStackmap(const CallInst &CI) {
> + // void @llvm.experimental.stackmap(i32 <id>, i32 <numShadowBytes>,
> + // [live variables...])
> +
> + assert(CI.getType()->isVoidTy() && "Stackmap cannot return a value.");
> +
> + SDValue Callee = getValue(CI.getCalledValue());
> +
> + // Lower into a call sequence with no args and no return value.
> + std::pair<SDValue, SDValue> Result = LowerCallOperands(CI, 0, 0, Callee);
> + // Set the root to the target-lowered call chain.
> + SDValue Chain = Result.second;
> + DAG.setRoot(Chain);
> +
> + /// Get a call instruction from the call sequence chain.
> + /// Tail calls are not allowed.
> + SDNode *CallEnd = Chain.getNode();
> + assert(CallEnd->getOpcode() == ISD::CALLSEQ_END &&
> + "Expected a callseq node.");
> + SDNode *Call = CallEnd->getOperand(0).getNode();
> + bool hasGlue = Call->getGluedNode();
> +
> + assert(Call->getNumOperands() == hasGlue ? 2 : 1 &&
> + "Unexpected extra stackmap call arguments.");
This assert has an order of evaluation logic error in it, and so it
could never fire. I fixed this in r193861, but the assert is now
firing on the build bots. Can you look into the failure?
Thanks!
~Aaron
More information about the llvm-commits
mailing list