forked from OSchip/llvm-project
[stackmaps] Legalise patchpoint arguments.
This is similar to D125680, but for llvm.experimental.patchpoint (instead of llvm.experimental.stackmap). Differential review: https://reviews.llvm.org/D129268
This commit is contained in:
parent
f8605da875
commit
2e62a26fd7
|
@ -1292,6 +1292,12 @@ enum NodeType {
|
|||
// Outputs: output chain, glue
|
||||
STACKMAP,
|
||||
|
||||
// The `llvm.experimental.patchpoint.*` intrinsic.
|
||||
// Operands: input chain, [glue], reg-mask, <id>, <numShadowBytes>, callee,
|
||||
// <numArgs>, cc, ...
|
||||
// Outputs: [rv], output chain, glue
|
||||
PATCHPOINT,
|
||||
|
||||
// Vector Predication
|
||||
#define BEGIN_REGISTER_VP_SDNODE(VPSDID, ...) VPSDID,
|
||||
#include "llvm/IR/VPIntrinsics.def"
|
||||
|
|
|
@ -321,7 +321,11 @@ private:
|
|||
|
||||
void Select_FREEZE(SDNode *N);
|
||||
void Select_ARITH_FENCE(SDNode *N);
|
||||
|
||||
void pushStackMapLiveVariable(SmallVectorImpl<SDValue> &Ops, SDValue Operand,
|
||||
SDLoc DL);
|
||||
void Select_STACKMAP(SDNode *N);
|
||||
void Select_PATCHPOINT(SDNode *N);
|
||||
|
||||
private:
|
||||
void DoInstructionSelection();
|
||||
|
|
|
@ -2918,6 +2918,9 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) {
|
|||
case ISD::STACKMAP:
|
||||
Res = SoftPromoteHalfOp_STACKMAP(N, OpNo);
|
||||
break;
|
||||
case ISD::PATCHPOINT:
|
||||
Res = SoftPromoteHalfOp_PATCHPOINT(N, OpNo);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Res.getNode())
|
||||
|
@ -3059,3 +3062,18 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_STACKMAP(SDNode *N, unsigned OpNo) {
|
|||
|
||||
return SDValue(); // Signal that we replaced the node ourselves.
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::SoftPromoteHalfOp_PATCHPOINT(SDNode *N,
|
||||
unsigned OpNo) {
|
||||
assert(OpNo >= 7);
|
||||
SmallVector<SDValue> NewOps(N->ops().begin(), N->ops().end());
|
||||
SDValue Op = N->getOperand(OpNo);
|
||||
NewOps[OpNo] = GetSoftPromotedHalf(Op);
|
||||
SDValue NewNode =
|
||||
DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), NewOps);
|
||||
|
||||
for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
|
||||
ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
|
||||
|
||||
return SDValue(); // Signal that we replaced the node ourselves.
|
||||
}
|
||||
|
|
|
@ -1727,6 +1727,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||
case ISD::STACKMAP:
|
||||
Res = PromoteIntOp_STACKMAP(N, OpNo);
|
||||
break;
|
||||
case ISD::PATCHPOINT:
|
||||
Res = PromoteIntOp_PATCHPOINT(N, OpNo);
|
||||
break;
|
||||
}
|
||||
|
||||
// If the result is null, the sub-method took care of registering results etc.
|
||||
|
@ -2341,6 +2344,15 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo) {
|
|||
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
|
||||
assert(OpNo >= 7);
|
||||
SmallVector<SDValue> NewOps(N->ops().begin(), N->ops().end());
|
||||
SDValue Operand = N->getOperand(OpNo);
|
||||
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), Operand.getValueType());
|
||||
NewOps[OpNo] = DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), NVT, Operand);
|
||||
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Integer Result Expansion
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -4693,6 +4705,9 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||
case ISD::STACKMAP:
|
||||
Res = ExpandIntOp_STACKMAP(N, OpNo);
|
||||
break;
|
||||
case ISD::PATCHPOINT:
|
||||
Res = ExpandIntOp_PATCHPOINT(N, OpNo);
|
||||
break;
|
||||
}
|
||||
|
||||
// If the result is null, the sub-method took care of registering results etc.
|
||||
|
@ -5524,30 +5539,67 @@ SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) {
|
|||
|
||||
SDValue DAGTypeLegalizer::ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo) {
|
||||
assert(OpNo > 1);
|
||||
|
||||
SDValue Op = N->getOperand(OpNo);
|
||||
SDLoc DL = SDLoc(N);
|
||||
SmallVector<SDValue> NewOps;
|
||||
|
||||
// FIXME: Non-constant operands are not yet handled:
|
||||
// - https://github.com/llvm/llvm-project/issues/26431
|
||||
// - https://github.com/llvm/llvm-project/issues/55957
|
||||
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
|
||||
if (!CN)
|
||||
return SDValue();
|
||||
|
||||
// Copy operands before the one being expanded.
|
||||
SmallVector<SDValue> NewOps;
|
||||
for (unsigned I = 0; I < OpNo; I++)
|
||||
NewOps.push_back(N->getOperand(I));
|
||||
|
||||
if (Op->getOpcode() == ISD::Constant) {
|
||||
ConstantSDNode *CN = cast<ConstantSDNode>(Op);
|
||||
EVT Ty = Op.getValueType();
|
||||
if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
|
||||
NewOps.push_back(
|
||||
DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
|
||||
NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
|
||||
} else {
|
||||
// FIXME: https://github.com/llvm/llvm-project/issues/55609
|
||||
return SDValue();
|
||||
}
|
||||
EVT Ty = Op.getValueType();
|
||||
SDLoc DL = SDLoc(N);
|
||||
if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
|
||||
NewOps.push_back(
|
||||
DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
|
||||
NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
|
||||
} else {
|
||||
// FIXME: Non-constant operands are not yet handled:
|
||||
// - https://github.com/llvm/llvm-project/issues/26431
|
||||
// - https://github.com/llvm/llvm-project/issues/55957
|
||||
// FIXME: https://github.com/llvm/llvm-project/issues/55609
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
// Copy remaining operands.
|
||||
for (unsigned I = OpNo + 1; I < N->getNumOperands(); I++)
|
||||
NewOps.push_back(N->getOperand(I));
|
||||
|
||||
SDValue NewNode = DAG.getNode(N->getOpcode(), DL, N->getVTList(), NewOps);
|
||||
|
||||
for (unsigned ResNum = 0; ResNum < N->getNumValues(); ResNum++)
|
||||
ReplaceValueWith(SDValue(N, ResNum), NewNode.getValue(ResNum));
|
||||
|
||||
return SDValue(); // Signal that we have replaced the node already.
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
|
||||
assert(OpNo >= 7);
|
||||
SDValue Op = N->getOperand(OpNo);
|
||||
|
||||
// FIXME: Non-constant operands are not yet handled:
|
||||
// - https://github.com/llvm/llvm-project/issues/26431
|
||||
// - https://github.com/llvm/llvm-project/issues/55957
|
||||
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Op);
|
||||
if (!CN)
|
||||
return SDValue();
|
||||
|
||||
// Copy operands before the one being expanded.
|
||||
SmallVector<SDValue> NewOps;
|
||||
for (unsigned I = 0; I < OpNo; I++)
|
||||
NewOps.push_back(N->getOperand(I));
|
||||
|
||||
EVT Ty = Op.getValueType();
|
||||
SDLoc DL = SDLoc(N);
|
||||
if (CN->getConstantIntValue()->getValue().getActiveBits() < 64) {
|
||||
NewOps.push_back(
|
||||
DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
|
||||
NewOps.push_back(DAG.getTargetConstant(CN->getZExtValue(), DL, Ty));
|
||||
} else {
|
||||
// FIXME: https://github.com/llvm/llvm-project/issues/55609
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -403,6 +403,7 @@ private:
|
|||
SDValue PromoteIntOp_VP_REDUCE(SDNode *N, unsigned OpNo);
|
||||
SDValue PromoteIntOp_SET_ROUNDING(SDNode *N);
|
||||
SDValue PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo);
|
||||
SDValue PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo);
|
||||
|
||||
void PromoteSetCCOperands(SDValue &LHS,SDValue &RHS, ISD::CondCode Code);
|
||||
|
||||
|
@ -495,6 +496,7 @@ private:
|
|||
SDValue ExpandIntOp_ATOMIC_STORE(SDNode *N);
|
||||
SDValue ExpandIntOp_SPLAT_VECTOR(SDNode *N);
|
||||
SDValue ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo);
|
||||
SDValue ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo);
|
||||
|
||||
void IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
|
||||
ISD::CondCode &CCCode, const SDLoc &dl);
|
||||
|
@ -744,6 +746,7 @@ private:
|
|||
SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo);
|
||||
SDValue SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo);
|
||||
SDValue SoftPromoteHalfOp_STACKMAP(SDNode *N, unsigned OpNo);
|
||||
SDValue SoftPromoteHalfOp_PATCHPOINT(SDNode *N, unsigned OpNo);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Scalarization Support: LegalizeVectorTypes.cpp
|
||||
|
|
|
@ -9302,19 +9302,18 @@ void SelectionDAGBuilder::populateCallLoweringInfo(
|
|||
static void addStackMapLiveVars(const CallBase &Call, unsigned StartIdx,
|
||||
const SDLoc &DL, SmallVectorImpl<SDValue> &Ops,
|
||||
SelectionDAGBuilder &Builder) {
|
||||
for (unsigned i = StartIdx, e = Call.arg_size(); i != e; ++i) {
|
||||
SDValue OpVal = Builder.getValue(Call.getArgOperand(i));
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(OpVal)) {
|
||||
Ops.push_back(
|
||||
Builder.DAG.getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
|
||||
Ops.push_back(
|
||||
Builder.DAG.getTargetConstant(C->getSExtValue(), DL, MVT::i64));
|
||||
} else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(OpVal)) {
|
||||
const TargetLowering &TLI = Builder.DAG.getTargetLoweringInfo();
|
||||
Ops.push_back(Builder.DAG.getTargetFrameIndex(
|
||||
FI->getIndex(), TLI.getFrameIndexTy(Builder.DAG.getDataLayout())));
|
||||
} else
|
||||
Ops.push_back(OpVal);
|
||||
SelectionDAG &DAG = Builder.DAG;
|
||||
for (unsigned I = StartIdx; I < Call.arg_size(); I++) {
|
||||
SDValue Op = Builder.getValue(Call.getArgOperand(I));
|
||||
|
||||
// Things on the stack are pointer-typed, meaning that they are already
|
||||
// legal and can be emitted directly to target nodes.
|
||||
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) {
|
||||
Ops.push_back(DAG.getTargetFrameIndex(FI->getIndex(), Op.getValueType()));
|
||||
} else {
|
||||
// Otherwise emit a target independent node to be legalised.
|
||||
Ops.push_back(Builder.getValue(Call.getArgOperand(I)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9366,20 +9365,7 @@ void SelectionDAGBuilder::visitStackmap(const CallInst &CI) {
|
|||
Ops.push_back(ShadConst);
|
||||
|
||||
// Add the live variables.
|
||||
for (unsigned I = 2; I < CI.arg_size(); I++) {
|
||||
SDValue Op = getValue(CI.getArgOperand(I));
|
||||
|
||||
// Things on the stack are pointer-typed, meaning that they are already
|
||||
// legal and can be emitted directly to target nodes.
|
||||
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) {
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
Ops.push_back(DAG.getTargetFrameIndex(
|
||||
FI->getIndex(), TLI.getFrameIndexTy(DAG.getDataLayout())));
|
||||
} else {
|
||||
// Otherwise emit a target independent node to be legalised.
|
||||
Ops.push_back(getValue(CI.getArgOperand(I)));
|
||||
}
|
||||
}
|
||||
addStackMapLiveVars(CI, 2, DL, Ops, *this);
|
||||
|
||||
// Create the STACKMAP node.
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
|
||||
|
@ -9456,6 +9442,19 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
|
|||
// Replace the target specific call node with the patchable intrinsic.
|
||||
SmallVector<SDValue, 8> Ops;
|
||||
|
||||
// Push the chain.
|
||||
Ops.push_back(*(Call->op_begin()));
|
||||
|
||||
// Optionally, push the glue (if any).
|
||||
if (HasGlue)
|
||||
Ops.push_back(*(Call->op_end() - 1));
|
||||
|
||||
// Push the register mask info.
|
||||
if (HasGlue)
|
||||
Ops.push_back(*(Call->op_end() - 2));
|
||||
else
|
||||
Ops.push_back(*(Call->op_end() - 1));
|
||||
|
||||
// Add the <id> and <numBytes> constants.
|
||||
SDValue IDVal = getValue(CB.getArgOperand(PatchPointOpers::IDPos));
|
||||
Ops.push_back(DAG.getTargetConstant(
|
||||
|
@ -9484,27 +9483,13 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
|
|||
for (unsigned i = NumMetaOpers, e = NumMetaOpers + NumArgs; i != e; ++i)
|
||||
Ops.push_back(getValue(CB.getArgOperand(i)));
|
||||
|
||||
// Push the arguments from the call instruction up to the register mask.
|
||||
// Push the arguments from the call instruction.
|
||||
SDNode::op_iterator e = HasGlue ? Call->op_end()-2 : Call->op_end()-1;
|
||||
Ops.append(Call->op_begin() + 2, e);
|
||||
|
||||
// Push live variables for the stack map.
|
||||
addStackMapLiveVars(CB, NumMetaOpers + NumArgs, dl, Ops, *this);
|
||||
|
||||
// Push the register mask info.
|
||||
if (HasGlue)
|
||||
Ops.push_back(*(Call->op_end()-2));
|
||||
else
|
||||
Ops.push_back(*(Call->op_end()-1));
|
||||
|
||||
// Push the chain (this is originally the first operand of the call, but
|
||||
// becomes now the last or second to last operand).
|
||||
Ops.push_back(*(Call->op_begin()));
|
||||
|
||||
// Push the glue flag (last operand).
|
||||
if (HasGlue)
|
||||
Ops.push_back(*(Call->op_end()-1));
|
||||
|
||||
SDVTList NodeTys;
|
||||
if (IsAnyRegCC && HasDef) {
|
||||
// Create the return types based on the intrinsic definition
|
||||
|
@ -9521,13 +9506,12 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
|
|||
NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
|
||||
|
||||
// Replace the target specific call node with a PATCHPOINT node.
|
||||
MachineSDNode *MN = DAG.getMachineNode(TargetOpcode::PATCHPOINT,
|
||||
dl, NodeTys, Ops);
|
||||
SDValue PPV = DAG.getNode(ISD::PATCHPOINT, dl, NodeTys, Ops);
|
||||
|
||||
// Update the NodeMap.
|
||||
if (HasDef) {
|
||||
if (IsAnyRegCC)
|
||||
setValue(&CB, SDValue(MN, 0));
|
||||
setValue(&CB, SDValue(PPV.getNode(), 0));
|
||||
else
|
||||
setValue(&CB, Result.first);
|
||||
}
|
||||
|
@ -9538,10 +9522,10 @@ void SelectionDAGBuilder::visitPatchpoint(const CallBase &CB,
|
|||
// value.
|
||||
if (IsAnyRegCC && HasDef) {
|
||||
SDValue From[] = {SDValue(Call, 0), SDValue(Call, 1)};
|
||||
SDValue To[] = {SDValue(MN, 1), SDValue(MN, 2)};
|
||||
SDValue To[] = {PPV.getValue(1), PPV.getValue(2)};
|
||||
DAG.ReplaceAllUsesOfValuesWith(From, To, 2);
|
||||
} else
|
||||
DAG.ReplaceAllUsesWith(Call, MN);
|
||||
DAG.ReplaceAllUsesWith(Call, PPV.getNode());
|
||||
DAG.DeleteNode(Call);
|
||||
|
||||
// Inform the Frame Information that we have a patchpoint in this function.
|
||||
|
|
|
@ -488,6 +488,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
|||
case ISD::VECREDUCE_FMIN: return "vecreduce_fmin";
|
||||
case ISD::STACKMAP:
|
||||
return "stackmap";
|
||||
case ISD::PATCHPOINT:
|
||||
return "patchpoint";
|
||||
|
||||
// Vector Predication
|
||||
#define BEGIN_REGISTER_VP_SDNODE(SDID, LEGALARG, NAME, ...) \
|
||||
|
|
|
@ -2193,8 +2193,27 @@ void SelectionDAGISel::Select_ARITH_FENCE(SDNode *N) {
|
|||
N->getOperand(0));
|
||||
}
|
||||
|
||||
void SelectionDAGISel::pushStackMapLiveVariable(SmallVectorImpl<SDValue> &Ops,
|
||||
SDValue OpVal, SDLoc DL) {
|
||||
SDNode *OpNode = OpVal.getNode();
|
||||
|
||||
// FrameIndex nodes should have been directly emitted to TargetFrameIndex
|
||||
// nodes at DAG-construction time.
|
||||
assert(OpNode->getOpcode() != ISD::FrameIndex);
|
||||
|
||||
if (OpNode->getOpcode() == ISD::Constant) {
|
||||
Ops.push_back(
|
||||
CurDAG->getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
|
||||
Ops.push_back(
|
||||
CurDAG->getTargetConstant(cast<ConstantSDNode>(OpNode)->getZExtValue(),
|
||||
DL, OpVal.getValueType()));
|
||||
} else {
|
||||
Ops.push_back(OpVal);
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionDAGISel::Select_STACKMAP(SDNode *N) {
|
||||
std::vector<SDValue> Ops;
|
||||
SmallVector<SDValue, 32> Ops;
|
||||
auto *It = N->op_begin();
|
||||
SDLoc DL(N);
|
||||
|
||||
|
@ -2213,24 +2232,8 @@ void SelectionDAGISel::Select_STACKMAP(SDNode *N) {
|
|||
Ops.push_back(Shad);
|
||||
|
||||
// Live variable operands.
|
||||
for (; It != N->op_end(); It++) {
|
||||
SDNode *OpNode = It->getNode();
|
||||
SDValue O;
|
||||
|
||||
// FrameIndex nodes should have been directly emitted to TargetFrameIndex
|
||||
// nodes at DAG-construction time.
|
||||
assert(OpNode->getOpcode() != ISD::FrameIndex);
|
||||
|
||||
if (OpNode->getOpcode() == ISD::Constant) {
|
||||
Ops.push_back(
|
||||
CurDAG->getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
|
||||
O = CurDAG->getTargetConstant(
|
||||
cast<ConstantSDNode>(OpNode)->getZExtValue(), DL, It->getValueType());
|
||||
} else {
|
||||
O = *It;
|
||||
}
|
||||
Ops.push_back(O);
|
||||
}
|
||||
for (; It != N->op_end(); It++)
|
||||
pushStackMapLiveVariable(Ops, *It, DL);
|
||||
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(InFlag);
|
||||
|
@ -2239,6 +2242,57 @@ void SelectionDAGISel::Select_STACKMAP(SDNode *N) {
|
|||
CurDAG->SelectNodeTo(N, TargetOpcode::STACKMAP, NodeTys, Ops);
|
||||
}
|
||||
|
||||
void SelectionDAGISel::Select_PATCHPOINT(SDNode *N) {
|
||||
SmallVector<SDValue, 32> Ops;
|
||||
auto *It = N->op_begin();
|
||||
SDLoc DL(N);
|
||||
|
||||
// Cache arguments that will be moved to the end in the target node.
|
||||
SDValue Chain = *It++;
|
||||
Optional<SDValue> Glue;
|
||||
if (It->getValueType() == MVT::Glue)
|
||||
Glue = *It++;
|
||||
SDValue RegMask = *It++;
|
||||
|
||||
// <id> operand.
|
||||
SDValue ID = *It++;
|
||||
assert(ID.getValueType() == MVT::i64);
|
||||
Ops.push_back(ID);
|
||||
|
||||
// <numShadowBytes> operand.
|
||||
SDValue Shad = *It++;
|
||||
assert(Shad.getValueType() == MVT::i32);
|
||||
Ops.push_back(Shad);
|
||||
|
||||
// Add the callee.
|
||||
Ops.push_back(*It++);
|
||||
|
||||
// Add <numArgs>.
|
||||
SDValue NumArgs = *It++;
|
||||
assert(NumArgs.getValueType() == MVT::i32);
|
||||
Ops.push_back(NumArgs);
|
||||
|
||||
// Calling convention.
|
||||
Ops.push_back(*It++);
|
||||
|
||||
// Push the args for the call.
|
||||
for (uint64_t I = cast<ConstantSDNode>(NumArgs)->getZExtValue(); I != 0; I--)
|
||||
Ops.push_back(*It++);
|
||||
|
||||
// Now push the live variables.
|
||||
for (; It != N->op_end(); It++)
|
||||
pushStackMapLiveVariable(Ops, *It, DL);
|
||||
|
||||
// Finally, the regmask, chain and (if present) glue are moved to the end.
|
||||
Ops.push_back(RegMask);
|
||||
Ops.push_back(Chain);
|
||||
if (Glue.hasValue())
|
||||
Ops.push_back(Glue.getValue());
|
||||
|
||||
SDVTList NodeTys = N->getVTList();
|
||||
CurDAG->SelectNodeTo(N, TargetOpcode::PATCHPOINT, NodeTys, Ops);
|
||||
}
|
||||
|
||||
/// GetVBR - decode a vbr encoding whose top bit is set.
|
||||
LLVM_ATTRIBUTE_ALWAYS_INLINE static uint64_t
|
||||
GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
|
||||
|
@ -2796,6 +2850,9 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
|
|||
case ISD::STACKMAP:
|
||||
Select_STACKMAP(NodeToMatch);
|
||||
return;
|
||||
case ISD::PATCHPOINT:
|
||||
Select_PATCHPOINT(NodeToMatch);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");
|
||||
|
|
|
@ -81,14 +81,14 @@
|
|||
; CHECK-NEXT: .hword 8
|
||||
; CHECK-NEXT: .hword 0
|
||||
; CHECK-NEXT: .hword 0
|
||||
; CHECK-NEXT: .word -1
|
||||
; CHECK-NEXT: .word 65535
|
||||
; SmallConstant
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .hword 8
|
||||
; CHECK-NEXT: .hword 0
|
||||
; CHECK-NEXT: .hword 0
|
||||
; CHECK-NEXT: .word -1
|
||||
; CHECK-NEXT: .word 65535
|
||||
; SmallConstant
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
|
|
|
@ -84,14 +84,14 @@
|
|||
; CHECK-NEXT: .short 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long -1
|
||||
; CHECK-NEXT: .long 65535
|
||||
; SmallConstant
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long -1
|
||||
; CHECK-NEXT: .long 65535
|
||||
; SmallConstant
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -enable-patchpoint-liveness=false | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
|
||||
; CHECK-NEXT: __LLVM_StackMaps:
|
||||
|
||||
; Header
|
||||
; CHECK-NEXT: .byte 3
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 0
|
||||
|
||||
; NumFunctions
|
||||
; CHECK-NEXT: .long 1
|
||||
; NumConstants
|
||||
; CHECK-NEXT: .long 0
|
||||
; NumRecords
|
||||
; CHECK-NEXT: .long 1
|
||||
|
||||
; StackSizeRecord[NumFunctions]
|
||||
; StackSizeRecord[0]
|
||||
; CHECK-NEXT: .quad _main
|
||||
; CHECK-NEXT: .quad 24
|
||||
; CHECK-NEXT: .quad 1
|
||||
|
||||
; Constants[NumConstants] (empty)
|
||||
|
||||
; StkMapRecord[NumRecords]
|
||||
; StkMapRecord[0]
|
||||
; CHECK-NEXT: .quad 0
|
||||
; CHECK-NEXT: .long {{.*}}
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; NumLocations
|
||||
; CHECK-NEXT: .short 11
|
||||
; Location[NumLocations]
|
||||
; Location[0]
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 1
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
; Location[1]
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 22
|
||||
; Location[2]
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 1
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
; Location[3]
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 16
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
; Location[4]
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 16
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
; Location[5]
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 8
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 66
|
||||
; Location[6]
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 4
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
; Location[7]
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
; Location[8]
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 4
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
; Location[9]
|
||||
; CHECK-NEXT: .byte 4
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 8
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
; Location[10]
|
||||
; CHECK-NEXT: .byte 1
|
||||
; CHECK-NEXT: .byte 0
|
||||
; CHECK-NEXT: .short 1
|
||||
; CHECK-NEXT: .short {{.*}}
|
||||
; CHECK-NEXT: .short 0
|
||||
; CHECK-NEXT: .long 0
|
||||
|
||||
@p32 = external global i8 addrspace(270)*
|
||||
|
||||
%struct1 = type {i32, i64}
|
||||
%struct2 = type {i1, i1, i1}
|
||||
|
||||
declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
|
||||
|
||||
define dso_local i32 @main(i32 %argc, i8** %argv) {
|
||||
entry:
|
||||
%i1reg = icmp eq i32 %argc, 5
|
||||
%i7reg = zext i1 %i1reg to i7
|
||||
%halfreg = sitofp i32 %argc to half
|
||||
%ptr32 = load i8 addrspace(270)*, i8 addrspace(270)** @p32
|
||||
%structreg1 = insertvalue %struct1 zeroinitializer, i32 %argc, 0
|
||||
%structreg2 = insertvalue %struct2 zeroinitializer, i1 %i1reg, 0
|
||||
call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(
|
||||
i64 0,
|
||||
i32 0,
|
||||
i8* null,
|
||||
i32 0,
|
||||
i1 %i1reg,
|
||||
i7 22,
|
||||
i7 %i7reg,
|
||||
half 1.0,
|
||||
half %halfreg,
|
||||
i128 66,
|
||||
; FIXME: fix and test vectors. At the moment even legally sized vectors
|
||||
; are broken:
|
||||
; https://github.com/llvm/llvm-project/issues/55613
|
||||
;
|
||||
; FIXME: test non-constant i128 once these are fixed:
|
||||
; - https://github.com/llvm/llvm-project/issues/26431
|
||||
; - https://github.com/llvm/llvm-project/issues/55957
|
||||
i8 addrspace(270)* %ptr32,
|
||||
; FIXME: The stackmap record generated for structs is incorrect:
|
||||
; - https://github.com/llvm/llvm-project/issues/55649
|
||||
; - https://github.com/llvm/llvm-project/issues/55957
|
||||
%struct1 zeroinitializer,
|
||||
%struct1 %structreg1,
|
||||
%struct2 zeroinitializer,
|
||||
%struct2 %structreg2)
|
||||
ret i32 0
|
||||
}
|
Loading…
Reference in New Issue