llvm.org GIT mirror llvm / ea55ece
Revert "r225808 - [PowerPC] Add StackMap/PatchPoint support" Reverting this while I investiage buildbot failures (segfaulting in GetCostForDef at ScheduleDAGRRList.cpp:314). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225811 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 4 years ago
17 changed file(s) with 104 addition(s) and 1122 deletion(s). Raw diff Collapse all Expand all
219219 lowered according to the calling convention specified at the
220220 intrinsic's callsite. Variants of the intrinsic with non-void return
221221 type also return a value according to calling convention.
222
223 On PowerPC, note that the ```` must be the actual intended target of
224 the indirect call, not the function-descriptor address normally used as the
225 C/C++ function-pointer representation. As a result, the call target must be
226 local because no adjustment or restoration of the TOC pointer (in register r2)
227 will be performed.
228222
229223 Requesting zero patch point arguments is valid. In this case, all
230224 variable operands are handled just like
3333 #include "llvm/CodeGen/MachineInstrBuilder.h"
3434 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
3535 #include "llvm/CodeGen/MachineRegisterInfo.h"
36 #include "llvm/CodeGen/StackMaps.h"
3736 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
3837 #include "llvm/IR/Constants.h"
3938 #include "llvm/IR/DebugInfo.h"
6968 MapVector TOC;
7069 const PPCSubtarget &Subtarget;
7170 uint64_t TOCLabelID;
72 StackMaps SM;
7371 public:
7472 explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
7573 : AsmPrinter(TM, Streamer),
76 Subtarget(TM.getSubtarget()), TOCLabelID(0), SM(*this) {}
74 Subtarget(TM.getSubtarget()), TOCLabelID(0) {}
7775
7876 const char *getPassName() const override {
7977 return "PowerPC Assembly Printer";
9189 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
9290 unsigned AsmVariant, const char *ExtraCode,
9391 raw_ostream &O) override;
94
95 void EmitEndOfAsmFile(Module &M) override;
96
97 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
98 const MachineInstr &MI);
99 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
100 const MachineInstr &MI);
10192 };
10293
10394 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
324315 return TOCEntry;
325316 }
326317
327 void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) {
328 SM.serializeToStackMapSection();
329 }
330
331 void PPCAsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
332 const MachineInstr &MI) {
333 unsigned NumNOPBytes = MI.getOperand(1).getImm();
334
335 SM.recordStackMap(MI);
336 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
337
338 // Scan ahead to trim the shadow.
339 const MachineBasicBlock &MBB = *MI.getParent();
340 MachineBasicBlock::const_iterator MII(MI);
341 ++MII;
342 while (NumNOPBytes > 0) {
343 if (MII == MBB.end() || MII->isCall() ||
344 MII->getOpcode() == PPC::DBG_VALUE ||
345 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
346 MII->getOpcode() == TargetOpcode::STACKMAP)
347 break;
348 ++MII;
349 NumNOPBytes -= 4;
350 }
351
352 // Emit nops.
353 for (unsigned i = 0; i < NumNOPBytes; i += 4)
354 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::NOP));
355 }
356
357 // Lower a patchpoint of the form:
358 // [], , , ,
359 void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
360 const MachineInstr &MI) {
361 SM.recordPatchPoint(MI);
362 PatchPointOpers Opers(&MI);
363
364 int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
365 unsigned EncodedBytes = 0;
366 if (CallTarget) {
367 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
368 "High 16 bits of call target should be zero.");
369 unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
370 EncodedBytes = 6*4;
371 // Materialize the jump address:
372 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI8)
373 .addReg(ScratchReg)
374 .addImm((CallTarget >> 32) & 0xFFFF));
375 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::RLDIC)
376 .addReg(ScratchReg)
377 .addReg(ScratchReg)
378 .addImm(32).addImm(16));
379 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORIS8)
380 .addReg(ScratchReg)
381 .addReg(ScratchReg)
382 .addImm((CallTarget >> 16) & 0xFFFF));
383 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORI8)
384 .addReg(ScratchReg)
385 .addReg(ScratchReg)
386 .addImm(CallTarget & 0xFFFF));
387
388 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8).addReg(ScratchReg));
389 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTRL8));
390 }
391
392 // Emit padding.
393 unsigned NumBytes = Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
394 assert(NumBytes >= EncodedBytes &&
395 "Patchpoint can't request size less than the length of a call.");
396 assert((NumBytes - EncodedBytes) % 4 == 0 &&
397 "Invalid number of NOP bytes requested!");
398 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
399 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::NOP));
400 }
401318
402319 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
403320 /// the current output stream.
414331 default: break;
415332 case TargetOpcode::DBG_VALUE:
416333 llvm_unreachable("Should be handled target independently");
417 case TargetOpcode::STACKMAP:
418 return LowerSTACKMAP(OutStreamer, SM, *MI);
419 case TargetOpcode::PATCHPOINT:
420 return LowerPATCHPOINT(OutStreamer, SM, *MI);
421
422334 case PPC::MoveGOTtoLR: {
423335 // Transform %LR = MoveGOTtoLR
424336 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
+0
-35
lib/Target/PowerPC/PPCCallingConv.h less more
None //=== PPCCallingConv.h - PPC Custom Calling Convention Routines -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the custom routines for the PPC Calling Convention that
10 // aren't done by tablegen.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_TARGET_PPC_PPCCALLINGCONV_H
15 #define LLVM_LIB_TARGET_PPC_PPCCALLINGCONV_H
16
17 #include "llvm/CodeGen/CallingConvLower.h"
18 #include "llvm/IR/CallingConv.h"
19
20 namespace llvm {
21
22 inline bool CC_PPC_AnyReg_Error(unsigned &, MVT &, MVT &,
23 CCValAssign::LocInfo &, ISD::ArgFlagsTy &,
24 CCState &) {
25 llvm_unreachable("The AnyReg calling convention is only supported by the " \
26 "stackmap and patchpoint intrinsics.");
27 // gracefully fallback to PPC C calling convention on Release builds.
28 return false;
29 }
30
31 } // End llvm namespace
32
33 #endif
34
2727 // Return Value Calling Convention
2828 //===----------------------------------------------------------------------===//
2929
30 // PPC64 AnyReg return-value convention. No explicit register is specified for
31 // the return-value. The register allocator is allowed and expected to choose
32 // any free register.
33 //
34 // This calling convention is currently only supported by the stackmap and
35 // patchpoint intrinsics. All other uses will result in an assert on Debug
36 // builds. On Release builds we fallback to the PPC C calling convention.
37 def RetCC_PPC64_AnyReg : CallingConv<[
38 CCCustom<"CC_PPC_AnyReg_Error">
39 ]>;
40
4130 // Return-value convention for PowerPC
4231 def RetCC_PPC : CallingConv<[
43 CCIfCC<"CallingConv::AnyReg", CCDelegateTo>,
44
4532 // On PPC64, integer return values are always promoted to i64
4633 CCIfType<[i32, i1], CCIfSubtarget<"isPPC64()", CCPromoteToType>>,
4734 CCIfType<[i1], CCIfNotSubtarget<"isPPC64()", CCPromoteToType>>,
6350 CCAssignToReg<[VSH2, VSH3, VSH4, VSH5, VSH6, VSH7, VSH8, VSH9]>>
6451 ]>;
6552
66 // No explicit register is specified for the AnyReg calling convention. The
67 // register allocator may assign the arguments to any free register.
68 //
69 // This calling convention is currently only supported by the stackmap and
70 // patchpoint intrinsics. All other uses will result in an assert on Debug
71 // builds. On Release builds we fallback to the PPC C calling convention.
72 def CC_PPC64_AnyReg : CallingConv<[
73 CCCustom<"CC_PPC_AnyReg_Error">
74 ]>;
7553
7654 // Note that we don't currently have calling conventions for 64-bit
7755 // PowerPC, but handle all the complexities of the ABI in the lowering
8260 // Only handle ints and floats. All ints are promoted to i64.
8361 // Vector types and quadword ints are not handled.
8462 def CC_PPC64_ELF_FIS : CallingConv<[
85 CCIfCC<"CallingConv::AnyReg", CCDelegateTo>,
86
8763 CCIfType<[i1], CCPromoteToType>,
8864 CCIfType<[i8], CCPromoteToType>,
8965 CCIfType<[i16], CCPromoteToType>,
9773 // and multiple register returns are "supported" to avoid compile
9874 // errors, but none are handled by the fast selector.
9975 def RetCC_PPC64_ELF_FIS : CallingConv<[
100 CCIfCC<"CallingConv::AnyReg", CCDelegateTo>,
101
10276 CCIfType<[i1], CCPromoteToType>,
10377 CCIfType<[i8], CCPromoteToType>,
10478 CCIfType<[i16], CCPromoteToType>,
228202
229203 def CSR_NoRegs : CalleeSavedRegs<(add)>;
230204
231 def CSR_64_AllRegs: CalleeSavedRegs<(add X0, (sequence "X%u", 3, 10),
232 (sequence "X%u", 14, 31),
233 (sequence "F%u", 0, 31),
234 (sequence "CR%u", 0, 7))>;
235
236 def CSR_64_AllRegs_Altivec : CalleeSavedRegs<(add CSR_64_AllRegs,
237 (sequence "V%u", 0, 31))>;
238
239 def CSR_64_AllRegs_VSX : CalleeSavedRegs<(add CSR_64_AllRegs_Altivec,
240 (sequence "VSL%u", 0, 31),
241 (sequence "VSH%u", 0, 31))>;
242
1414
1515 #include "PPC.h"
1616 #include "MCTargetDesc/PPCPredicates.h"
17 #include "PPCCallingConv.h"
1817 #include "PPCISelLowering.h"
1918 #include "PPCSubtarget.h"
2019 #include "PPCTargetMachine.h"
119118 unsigned Op0, bool Op0IsKill,
120119 unsigned Op1, bool Op1IsKill);
121120
122 bool fastLowerCall(CallLoweringInfo &CLI) override;
123
124121 // Instruction selection routines.
125122 private:
126123 bool SelectLoad(const Instruction *I);
132129 bool SelectIToFP(const Instruction *I, bool IsSigned);
133130 bool SelectFPToI(const Instruction *I, bool IsSigned);
134131 bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode);
132 bool SelectCall(const Instruction *I);
135133 bool SelectRet(const Instruction *I);
136134 bool SelectTrunc(const Instruction *I);
137135 bool SelectIntExt(const Instruction *I);
175173 CallingConv::ID CC,
176174 unsigned &NumBytes,
177175 bool IsVarArg);
178 bool finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes);
176 void finishCall(MVT RetVT, SmallVectorImpl &UsedRegs,
177 const Instruction *I, CallingConv::ID CC,
178 unsigned &NumBytes, bool IsVarArg);
179179 CCAssignFn *usePPC32CCs(unsigned Flag);
180180
181181 private:
13381338
13391339 // For a call that we've determined we can fast-select, finish the
13401340 // call sequence and generate a copy to obtain the return value (if any).
1341 bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes) {
1342 CallingConv::ID CC = CLI.CallConv;
1343
1341 void PPCFastISel::finishCall(MVT RetVT, SmallVectorImpl &UsedRegs,
1342 const Instruction *I, CallingConv::ID CC,
1343 unsigned &NumBytes, bool IsVarArg) {
13441344 // Issue CallSEQ_END.
13451345 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
13461346 TII.get(TII.getCallFrameDestroyOpcode()))
13511351 // any real difficulties there.
13521352 if (RetVT != MVT::isVoid) {
13531353 SmallVector RVLocs;
1354 CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);
1354 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
13551355 CCInfo.AnalyzeCallResult(RetVT, RetCC_PPC64_ELF_FIS);
13561356 CCValAssign &VA = RVLocs[0];
13571357 assert(RVLocs.size() == 1 && "No support for multi-reg return values!");
13961396 }
13971397
13981398 assert(ResultReg && "ResultReg unset!");
1399 CLI.InRegs.push_back(SourcePhysReg);
1400 CLI.ResultReg = ResultReg;
1401 CLI.NumResultRegs = 1;
1402 }
1403
1404 return true;
1405 }
1406
1407 bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
1408 CallingConv::ID CC = CLI.CallConv;
1409 bool IsTailCall = CLI.IsTailCall;
1410 bool IsVarArg = CLI.IsVarArg;
1411 const Value *Callee = CLI.Callee;
1412 const char *SymName = CLI.SymName;
1413
1414 if (!Callee && !SymName)
1399 UsedRegs.push_back(SourcePhysReg);
1400 updateValueMap(I, ResultReg);
1401 }
1402 }
1403
1404 // Attempt to fast-select a call instruction.
1405 bool PPCFastISel::SelectCall(const Instruction *I) {
1406 const CallInst *CI = cast(I);
1407 const Value *Callee = CI->getCalledValue();
1408
1409 // Can't handle inline asm.
1410 if (isa(Callee))
14151411 return false;
14161412
14171413 // Allow SelectionDAG isel to handle tail calls.
1418 if (IsTailCall)
1419 return false;
1420
1421 // Let SDISel handle vararg functions.
1414 if (CI->isTailCall())
1415 return false;
1416
1417 // Obtain calling convention.
1418 ImmutableCallSite CS(CI);
1419 CallingConv::ID CC = CS.getCallingConv();
1420
1421 PointerType *PT = cast(CS.getCalledValue()->getType());
1422 FunctionType *FTy = cast(PT->getElementType());
1423 bool IsVarArg = FTy->isVarArg();
1424
1425 // Not ready for varargs yet.
14221426 if (IsVarArg)
14231427 return false;
14241428
14251429 // Handle simple calls for now, with legal return types and
14261430 // those that can be extended.
1427 Type *RetTy = CLI.RetTy;
1431 Type *RetTy = I->getType();
14281432 MVT RetVT;
14291433 if (RetTy->isVoidTy())
14301434 RetVT = MVT::isVoid;
14451449
14461450 // Bail early if more than 8 arguments, as we only currently
14471451 // handle arguments passed in registers.
1448 unsigned NumArgs = CLI.OutVals.size();
1452 unsigned NumArgs = CS.arg_size();
14491453 if (NumArgs > 8)
14501454 return false;
14511455
14601464 ArgVTs.reserve(NumArgs);
14611465 ArgFlags.reserve(NumArgs);
14621466
1463 for (unsigned i = 0, ie = NumArgs; i != ie; ++i) {
1467 for (ImmutableCallSite::arg_iterator II = CS.arg_begin(), IE = CS.arg_end();
1468 II != IE; ++II) {
1469 // FIXME: ARM does something for intrinsic calls here, check into that.
1470
1471 unsigned AttrIdx = II - CS.arg_begin() + 1;
1472
14641473 // Only handle easy calls for now. It would be reasonably easy
14651474 // to handle <= 8-byte structures passed ByVal in registers, but we
14661475 // have to ensure they are right-justified in the register.
1467 ISD::ArgFlagsTy Flags = CLI.OutFlags[i];
1468 if (Flags.isInReg() || Flags.isSRet() || Flags.isNest() || Flags.isByVal())
1476 if (CS.paramHasAttr(AttrIdx, Attribute::InReg) ||
1477 CS.paramHasAttr(AttrIdx, Attribute::StructRet) ||
1478 CS.paramHasAttr(AttrIdx, Attribute::Nest) ||
1479 CS.paramHasAttr(AttrIdx, Attribute::ByVal))
14691480 return false;
14701481
1471 Value *ArgValue = CLI.OutVals[i];
1472 Type *ArgTy = ArgValue->getType();
1482 ISD::ArgFlagsTy Flags;
1483 if (CS.paramHasAttr(AttrIdx, Attribute::SExt))
1484 Flags.setSExt();
1485 if (CS.paramHasAttr(AttrIdx, Attribute::ZExt))
1486 Flags.setZExt();
1487
1488 Type *ArgTy = (*II)->getType();
14731489 MVT ArgVT;
14741490 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
14751491 return false;
14771493 if (ArgVT.isVector())
14781494 return false;
14791495
1480 unsigned Arg = getRegForValue(ArgValue);
1496 unsigned Arg = getRegForValue(*II);
14811497 if (Arg == 0)
14821498 return false;
14831499
1484 Args.push_back(ArgValue);
1500 unsigned OriginalAlignment = DL.getABITypeAlignment(ArgTy);
1501 Flags.setOrigAlign(OriginalAlignment);
1502
1503 Args.push_back(*II);
14851504 ArgRegs.push_back(Arg);
14861505 ArgVTs.push_back(ArgVT);
14871506 ArgFlags.push_back(Flags);
14951514 RegArgs, CC, NumBytes, IsVarArg))
14961515 return false;
14971516
1498 MachineInstrBuilder MIB;
14991517 // FIXME: No handling for function pointers yet. This requires
15001518 // implementing the function descriptor (OPD) setup.
15011519 const GlobalValue *GV = dyn_cast(Callee);
1502 if (!GV) {
1503 // patchpoints are a special case; they always dispatch to a pointer value.
1504 // However, we don't actually want to generate the indirect call sequence
1505 // here (that will be generated, as necessary, during asm printing), and
1506 // the call we generate here will be erased by FastISel::selectPatchpoint,
1507 // so don't try very hard...
1508 if (CLI.IsPatchPoint)
1509 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(PPC::NOP));
1510 else
1511 return false;
1512 } else {
1513 // Build direct call with NOP for TOC restore.
1514 // FIXME: We can and should optimize away the NOP for local calls.
1515 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1516 TII.get(PPC::BL8_NOP));
1517 // Add callee.
1518 MIB.addGlobalAddress(GV);
1519 }
1520 if (!GV)
1521 return false;
1522
1523 // Build direct call with NOP for TOC restore.
1524 // FIXME: We can and should optimize away the NOP for local calls.
1525 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1526 TII.get(PPC::BL8_NOP));
1527 // Add callee.
1528 MIB.addGlobalAddress(GV);
15201529
15211530 // Add implicit physical register uses to the call.
15221531 for (unsigned II = 0, IE = RegArgs.size(); II != IE; ++II)
15301539 // defs for return values will be added by setPhysRegsDeadExcept().
15311540 MIB.addRegMask(TRI.getCallPreservedMask(CC));
15321541
1533 CLI.Call = MIB;
1534
15351542 // Finish off the call including any return values.
1536 return finishCall(RetVT, CLI, NumBytes);
1543 SmallVector UsedRegs;
1544 finishCall(RetVT, UsedRegs, I, CC, NumBytes, IsVarArg);
1545
1546 // Set all unused physregs defs as dead.
1547 static_cast(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
1548
1549 return true;
15371550 }
15381551
15391552 // Attempt to fast-select a return instruction.
18231836 case Instruction::Sub:
18241837 return SelectBinaryIntOp(I, ISD::SUB);
18251838 case Instruction::Call:
1826 return selectCall(I);
1839 if (dyn_cast(I))
1840 return false;
1841 return SelectCall(I);
18271842 case Instruction::Ret:
18281843 return SelectRet(I);
18291844 case Instruction::Trunc:
449449
450450 return MF.getTarget().Options.DisableFramePointerElim(MF) ||
451451 MFI->hasVarSizedObjects() ||
452 MFI->hasStackMap() || MFI->hasPatchPoint() ||
453452 (MF.getTarget().Options.GuaranteedTailCallOpt &&
454453 MF.getInfo()->hasFastCall());
455454 }
1212
1313 #include "PPCISelLowering.h"
1414 #include "MCTargetDesc/PPCPredicates.h"
15 #include "PPCCallingConv.h"
1615 #include "PPCMachineFunctionInfo.h"
1716 #include "PPCPerfectShuffle.h"
1817 #include "PPCTargetMachine.h"
35903589 static
35913590 unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
35923591 SDValue &Chain, SDLoc dl, int SPDiff, bool isTailCall,
3593 bool IsPatchPoint,
35943592 SmallVectorImpl > &RegsToPass,
35953593 SmallVectorImpl &Ops, std::vector &NodeTys,
35963594 const PPCSubtarget &Subtarget) {
36643662 // to do the call, we can't use PPCISD::CALL.
36653663 SDValue MTCTROps[] = {Chain, Callee, InFlag};
36663664
3667 if (isSVR4ABI && isPPC64 && !isELFv2ABI && !IsPatchPoint) {
3665 if (isSVR4ABI && isPPC64 && !isELFv2ABI) {
36683666 // Function pointers in the 64-bit SVR4 ABI do not point to the function
36693667 // entry point, but to the function descriptor (the function entry point
36703668 // address is part of the function descriptor though).
37333731 MTCTROps[2] = InFlag;
37343732 }
37353733
3736 if (!IsPatchPoint) {
3737 Chain = DAG.getNode(PPCISD::MTCTR, dl, NodeTys,
3738 makeArrayRef(MTCTROps, InFlag.getNode() ? 3 : 2));
3739 InFlag = Chain.getValue(1);
3740 }
3734 Chain = DAG.getNode(PPCISD::MTCTR, dl, NodeTys,
3735 makeArrayRef(MTCTROps, InFlag.getNode() ? 3 : 2));
3736 InFlag = Chain.getValue(1);
37413737
37423738 NodeTys.clear();
37433739 NodeTys.push_back(MVT::Other);
37463742 CallOpc = PPCISD::BCTRL;
37473743 Callee.setNode(nullptr);
37483744 // Add use of X11 (holding environment pointer)
3749 if (isSVR4ABI && isPPC64 && !isELFv2ABI && !IsPatchPoint)
3745 if (isSVR4ABI && isPPC64 && !isELFv2ABI)
37503746 Ops.push_back(DAG.getRegister(PPC::X11, PtrVT));
37513747 // Add CTR register as callee so a bctr can be emitted later.
37523748 if (isTailCall)
37863782 RegsToPass[i].second.getValueType()));
37873783
37883784 // Direct calls in the ELFv2 ABI need the TOC register live into the call.
3789 if (Callee.getNode() && isELFv2ABI && !IsPatchPoint)
3785 if (Callee.getNode() && isELFv2ABI)
37903786 Ops.push_back(DAG.getRegister(PPC::X2, PtrVT));
37913787
37923788 return CallOpc;
38493845
38503846 SDValue
38513847 PPCTargetLowering::FinishCall(CallingConv::ID CallConv, SDLoc dl,
3852 bool isTailCall, bool isVarArg, bool IsPatchPoint,
3848 bool isTailCall, bool isVarArg,
38533849 SelectionDAG &DAG,
38543850 SmallVector, 8>
38553851 &RegsToPass,
38633859 std::vector NodeTys;
38643860 SmallVector Ops;
38653861 unsigned CallOpc = PrepareCall(DAG, Callee, InFlag, Chain, dl, SPDiff,
3866 isTailCall, IsPatchPoint, RegsToPass, Ops,
3867 NodeTys, Subtarget);
3862 isTailCall, RegsToPass, Ops, NodeTys,
3863 Subtarget);
38683864
38693865 // Add implicit use of CR bit 6 for 32-bit SVR4 vararg calls
38703866 if (isVarArg && Subtarget.isSVR4ABI() && !Subtarget.isPPC64())
39663962 bool &isTailCall = CLI.IsTailCall;
39673963 CallingConv::ID CallConv = CLI.CallConv;
39683964 bool isVarArg = CLI.IsVarArg;
3969 bool IsPatchPoint = CLI.IsPatchPoint;
39703965
39713966 if (isTailCall)
39723967 isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,
39793974 if (Subtarget.isSVR4ABI()) {
39803975 if (Subtarget.isPPC64())
39813976 return LowerCall_64SVR4(Chain, Callee, CallConv, isVarArg,
3982 isTailCall, IsPatchPoint, Outs, OutVals, Ins,
3977 isTailCall, Outs, OutVals, Ins,
39833978 dl, DAG, InVals);
39843979 else
39853980 return LowerCall_32SVR4(Chain, Callee, CallConv, isVarArg,
3986 isTailCall, IsPatchPoint, Outs, OutVals, Ins,
3981 isTailCall, Outs, OutVals, Ins,
39873982 dl, DAG, InVals);
39883983 }
39893984
39903985 return LowerCall_Darwin(Chain, Callee, CallConv, isVarArg,
3991 isTailCall, IsPatchPoint, Outs, OutVals, Ins,
3986 isTailCall, Outs, OutVals, Ins,
39923987 dl, DAG, InVals);
39933988 }
39943989
39953990 SDValue
39963991 PPCTargetLowering::LowerCall_32SVR4(SDValue Chain, SDValue Callee,
39973992 CallingConv::ID CallConv, bool isVarArg,
3998 bool isTailCall, bool IsPatchPoint,
3993 bool isTailCall,
39993994 const SmallVectorImpl &Outs,
40003995 const SmallVectorImpl &OutVals,
40013996 const SmallVectorImpl &Ins,
42054200 PrepareTailCall(DAG, InFlag, Chain, dl, false, SPDiff, NumBytes, LROp, FPOp,
42064201 false, TailCallArguments);
42074202
4208 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
4203 return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG,
42094204 RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes,
42104205 Ins, InVals);
42114206 }
42334228 SDValue
42344229 PPCTargetLowering::LowerCall_64SVR4(SDValue Chain, SDValue Callee,
42354230 CallingConv::ID CallConv, bool isVarArg,
4236 bool isTailCall, bool IsPatchPoint,
4231 bool isTailCall,
42374232 const SmallVectorImpl &Outs,
42384233 const SmallVectorImpl &OutVals,
42394234 const SmallVectorImpl &Ins,
46694664 // Check if this is an indirect call (MTCTR/BCTRL).
46704665 // See PrepareCall() for more information about calls through function
46714666 // pointers in the 64-bit SVR4 ABI.
4672 if (!isTailCall && !IsPatchPoint &&
4667 if (!isTailCall &&
46734668 !isFunctionGlobalAddress(Callee) &&
46744669 !isa(Callee)) {
46754670 // Load r2 into a virtual register and store it to the TOC save area.
46834678 // In the ELFv2 ABI, R12 must contain the address of an indirect callee.
46844679 // This does not mean the MTCTR instruction must use R12; it's easier
46854680 // to model this as an extra parameter, so do that.
4686 if (isELFv2ABI && !IsPatchPoint)
4681 if (isELFv2ABI)
46874682 RegsToPass.push_back(std::make_pair((unsigned)PPC::X12, Callee));
46884683 }
46894684
47004695 PrepareTailCall(DAG, InFlag, Chain, dl, true, SPDiff, NumBytes, LROp,
47014696 FPOp, true, TailCallArguments);
47024697
4703 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
4698 return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG,
47044699 RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes,
47054700 Ins, InVals);
47064701 }
47084703 SDValue
47094704 PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee,
47104705 CallingConv::ID CallConv, bool isVarArg,
4711 bool isTailCall, bool IsPatchPoint,
4706 bool isTailCall,
47124707 const SmallVectorImpl &Outs,
47134708 const SmallVectorImpl &OutVals,
47144709 const SmallVectorImpl &Ins,
50935088 PrepareTailCall(DAG, InFlag, Chain, dl, isPPC64, SPDiff, NumBytes, LROp,
50945089 FPOp, true, TailCallArguments);
50955090
5096 return FinishCall(CallConv, dl, isTailCall, isVarArg, IsPatchPoint, DAG,
5091 return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG,
50975092 RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes,
50985093 Ins, InVals);
50995094 }
72507245 MachineBasicBlock *
72517246 PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
72527247 MachineBasicBlock *BB) const {
7253 if (MI->getOpcode() == TargetOpcode::STACKMAP ||
7254 MI->getOpcode() == TargetOpcode::PATCHPOINT)
7255 return emitPatchPoint(MI, BB);
7256
72577248 if (MI->getOpcode() == PPC::EH_SjLj_SetJmp32 ||
72587249 MI->getOpcode() == PPC::EH_SjLj_SetJmp64) {
72597250 return emitEHSjLjSetJmp(MI, BB);
98909881 return false;
98919882 }
98929883
9893 const MCPhysReg *
9894 PPCTargetLowering::getScratchRegisters(CallingConv::ID) const {
9895 // LR is a callee-save register, but we must treat it as clobbered by any call
9896 // site. Hence we include LR in the scratch registers, which are in turn added
9897 // as implicit-defs for stackmaps and patchpoints. The same reasoning applies
9898 // to CTR, which is used by any indirect call.
9899 static const MCPhysReg ScratchRegs[] = {
9900 PPC::X11, PPC::X12, PPC::LR8, PPC::CTR8, 0
9901 };
9902
9903 return ScratchRegs;
9904 }
9905
99069884 bool
99079885 PPCTargetLowering::shouldExpandBuildVectorWithShuffles(
99089886 EVT VT , unsigned DefinedValues) const {
568568 /// expanded to FMAs when this method returns true, otherwise fmuladd is
569569 /// expanded to fmul + fadd.
570570 bool isFMAFasterThanFMulAndFAdd(EVT VT) const override;
571
572 const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
573571
574572 // Should we expand the build vector with shuffles?
575573 bool
682680 SDLoc dl, SelectionDAG &DAG,
683681 SmallVectorImpl &InVals) const;
684682 SDValue FinishCall(CallingConv::ID CallConv, SDLoc dl, bool isTailCall,
685 bool isVarArg, bool IsPatchPoint,
683 bool isVarArg,
686684 SelectionDAG &DAG,
687685 SmallVector, 8>
688686 &RegsToPass,
747745 SDValue
748746 LowerCall_Darwin(SDValue Chain, SDValue Callee,
749747 CallingConv::ID CallConv,
750 bool isVarArg, bool isTailCall, bool IsPatchPoint,
748 bool isVarArg, bool isTailCall,
751749 const SmallVectorImpl &Outs,
752750 const SmallVectorImpl &OutVals,
753751 const SmallVectorImpl &Ins,
756754 SDValue
757755 LowerCall_64SVR4(SDValue Chain, SDValue Callee,
758756 CallingConv::ID CallConv,
759 bool isVarArg, bool isTailCall, bool IsPatchPoint,
757 bool isVarArg, bool isTailCall,
760758 const SmallVectorImpl &Outs,
761759 const SmallVectorImpl &OutVals,
762760 const SmallVectorImpl &Ins,
764762 SmallVectorImpl &InVals) const;
765763 SDValue
766764 LowerCall_32SVR4(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
767 bool isVarArg, bool isTailCall, bool IsPatchPoint,
765 bool isVarArg, bool isTailCall,
768766 const SmallVectorImpl &Outs,
769767 const SmallVectorImpl &OutVals,
770768 const SmallVectorImpl &Ins,
2828 #include "llvm/CodeGen/PseudoSourceValue.h"
2929 #include "llvm/CodeGen/ScheduleDAG.h"
3030 #include "llvm/CodeGen/SlotIndexes.h"
31 #include "llvm/CodeGen/StackMaps.h"
3231 #include "llvm/MC/MCAsmInfo.h"
3332 #include "llvm/Support/CommandLine.h"
3433 #include "llvm/Support/Debug.h"
15961595 const MachineFunction *MF = MI->getParent()->getParent();
15971596 const char *AsmStr = MI->getOperand(0).getSymbolName();
15981597 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
1599 } else if (Opcode == TargetOpcode::STACKMAP) {
1600 return MI->getOperand(1).getImm();
1601 } else if (Opcode == TargetOpcode::PATCHPOINT) {
1602 PatchPointOpers Opers(MI);
1603 return Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
16041598 } else {
16051599 const MCInstrDesc &Desc = get(Opcode);
16061600 return Desc.getSize();
9898
9999 const MCPhysReg*
100100 PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
101 if (MF->getFunction()->getCallingConv() == CallingConv::AnyReg) {
102 if (Subtarget.hasVSX())
103 return CSR_64_AllRegs_VSX_SaveList;
104 if (Subtarget.hasAltivec())
105 return CSR_64_AllRegs_Altivec_SaveList;
106 return CSR_64_AllRegs_SaveList;
107 }
108
109101 if (Subtarget.isDarwinABI())
110102 return Subtarget.isPPC64() ? (Subtarget.hasAltivec() ?
111103 CSR_Darwin64_Altivec_SaveList :
124116
125117 const uint32_t*
126118 PPCRegisterInfo::getCallPreservedMask(CallingConv::ID CC) const {
127 if (CC == CallingConv::AnyReg) {
128 if (Subtarget.hasVSX())
129 return CSR_64_AllRegs_VSX_RegMask;
130 if (Subtarget.hasAltivec())
131 return CSR_64_AllRegs_Altivec_RegMask;
132 return CSR_64_AllRegs_RegMask;
133 }
134
135119 if (Subtarget.isDarwinABI())
136120 return Subtarget.isPPC64() ? (Subtarget.hasAltivec() ?
137121 CSR_Darwin64_Altivec_RegMask :
151135 const uint32_t*
152136 PPCRegisterInfo::getNoPreservedMask() const {
153137 return CSR_NoRegs_RegMask;
154 }
155
156 void PPCRegisterInfo::adjustStackMapLiveOutMask(uint32_t *Mask) const {
157 unsigned PseudoRegs[] = { PPC::ZERO, PPC::ZERO8, PPC::RM };
158 for (unsigned i = 0, ie = array_lengthof(PseudoRegs); i != ie; ++i) {
159 unsigned Reg = PseudoRegs[i];
160 Mask[Reg / 32] &= ~(1u << (Reg % 32));
161 }
162138 }
163139
164140 BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
723699 // Take into account whether it's an add or mem instruction
724700 unsigned OffsetOperandNo = (FIOperandNum == 2) ? 1 : 2;
725701 if (MI.isInlineAsm())
726 OffsetOperandNo = FIOperandNum - 1;
727 else if (MI.getOpcode() == TargetOpcode::STACKMAP ||
728 MI.getOpcode() == TargetOpcode::PATCHPOINT)
729 OffsetOperandNo = FIOperandNum + 1;
702 OffsetOperandNo = FIOperandNum-1;
730703
731704 return OffsetOperandNo;
732705 }
798771
799772 // If the instruction is not present in ImmToIdxMap, then it has no immediate
800773 // form (and must be r+r).
801 bool noImmForm = !MI.isInlineAsm() && OpC != TargetOpcode::STACKMAP &&
802 OpC != TargetOpcode::PATCHPOINT && !ImmToIdxMap.count(OpC);
774 bool noImmForm = !MI.isInlineAsm() && !ImmToIdxMap.count(OpC);
803775
804776 // Now add the frame object offset to the offset from r1.
805777 int Offset = MFI->getObjectOffset(FrameIndex);
823795 // only "std" to a stack slot that is at least 4-byte aligned, but it can
824796 // happen in invalid code.
825797 assert(OpC != PPC::DBG_VALUE &&
826 "This should be handled in a target-independent way");
827 if (!noImmForm && ((isInt<16>(Offset) && (!isIXAddr || (Offset & 3) == 0)) ||
828 OpC == TargetOpcode::STACKMAP ||
829 OpC == TargetOpcode::PATCHPOINT)) {
798 "This should be handle in a target independent way");
799 if (!noImmForm && isInt<16>(Offset) && (!isIXAddr || (Offset & 3) == 0)) {
830800 MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
831801 return;
832802 }
10371007 Offset += MI->getOperand(OffsetOperandNo).getImm();
10381008
10391009 return MI->getOpcode() == PPC::DBG_VALUE || // DBG_VALUE is always Reg+Imm
1040 MI->getOpcode() == TargetOpcode::STACKMAP ||
1041 MI->getOpcode() == TargetOpcode::PATCHPOINT ||
10421010 (isInt<16>(Offset) && (!usesIXAddr(*MI) || (Offset & 3) == 0));
10431011 }
10441012
4747 getCalleeSavedRegs(const MachineFunction* MF =nullptr) const override;
4848 const uint32_t *getCallPreservedMask(CallingConv::ID CC) const override;
4949 const uint32_t *getNoPreservedMask() const;
50
51 void adjustStackMapLiveOutMask(uint32_t *Mask) const override;
5250
5351 BitVector getReservedRegs(const MachineFunction &MF) const override;
5452
180180 case Intrinsic::ssub_with_overflow:
181181 case Intrinsic::usub_with_overflow:
182182 if ((Idx == 1) && Imm.getBitWidth() <= 64 && isInt<16>(Imm.getSExtValue()))
183 return TCC_Free;
184 break;
185 case Intrinsic::experimental_stackmap:
186 if ((Idx < 2) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
187 return TCC_Free;
188 break;
189 case Intrinsic::experimental_patchpoint_void:
190 case Intrinsic::experimental_patchpoint_i64:
191 if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue())))
192183 return TCC_Free;
193184 break;
194185 }
+0
-19
test/CodeGen/PowerPC/ppc64-anyregcc-crash.ll less more
None ; RUN: not llc < %s -mtriple=powerpc64-unknown-linux-gnu 2>&1 | FileCheck %s
1 ;
2 ; Check that misuse of anyregcc results in a compile time error.
3
4 ; CHECK: LLVM ERROR: ran out of registers during register allocation
5 define i64 @anyreglimit(i64 %v1, i64 %v2, i64 %v3, i64 %v4, i64 %v5, i64 %v6, i64 %v7, i64 %v8,
6 i64 %v9, i64 %v10, i64 %v11, i64 %v12, i64 %v13, i64 %v14, i64 %v15, i64 %v16,
7 i64 %v17, i64 %v18, i64 %v19, i64 %v20, i64 %v21, i64 %v22, i64 %v23, i64 %v24,
8 i64 %v25, i64 %v26, i64 %v27, i64 %v28, i64 %v29, i64 %v30, i64 %v31, i64 %v32) {
9 entry:
10 %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 12, i32 15, i8* inttoptr (i64 0 to i8*), i32 32,
11 i64 %v1, i64 %v2, i64 %v3, i64 %v4, i64 %v5, i64 %v6, i64 %v7, i64 %v8,
12 i64 %v9, i64 %v10, i64 %v11, i64 %v12, i64 %v13, i64 %v14, i64 %v15, i64 %v16,
13 i64 %v17, i64 %v18, i64 %v19, i64 %v20, i64 %v21, i64 %v22, i64 %v23, i64 %v24,
14 i64 %v25, i64 %v26, i64 %v27, i64 %v28, i64 %v29, i64 %v30, i64 %v31, i64 %v32)
15 ret i64 %result
16 }
17
18 declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)
+0
-367
test/CodeGen/PowerPC/ppc64-anyregcc.ll less more
None ; RUN: llc < %s | FileCheck %s
1 target datalayout = "E-m:e-i64:64-n32:64"
2 target triple = "powerpc64-unknown-linux-gnu"
3
4 ; Stackmap Header: no constants - 6 callsites
5 ; CHECK-LABEL: .section .llvm_stackmaps
6 ; CHECK-NEXT: __LLVM_StackMaps:
7 ; Header
8 ; CHECK-NEXT: .byte 1
9 ; CHECK-NEXT: .byte 0
10 ; CHECK-NEXT: .short 0
11 ; Num Functions
12 ; CHECK-NEXT: .long 8
13 ; Num LargeConstants
14 ; CHECK-NEXT: .long 0
15 ; Num Callsites
16 ; CHECK-NEXT: .long 8
17
18 ; Functions and stack size
19 ; CHECK-NEXT: .quad test
20 ; CHECK-NEXT: .quad 128
21 ; CHECK-NEXT: .quad property_access1
22 ; CHECK-NEXT: .quad 128
23 ; CHECK-NEXT: .quad property_access2
24 ; CHECK-NEXT: .quad 128
25 ; CHECK-NEXT: .quad property_access3
26 ; CHECK-NEXT: .quad 128
27 ; CHECK-NEXT: .quad anyreg_test1
28 ; CHECK-NEXT: .quad 160
29 ; CHECK-NEXT: .quad anyreg_test2
30 ; CHECK-NEXT: .quad 160
31 ; CHECK-NEXT: .quad patchpoint_spilldef
32 ; CHECK-NEXT: .quad 256
33 ; CHECK-NEXT: .quad patchpoint_spillargs
34 ; CHECK-NEXT: .quad 288
35
36
37 ; test
38 ; CHECK-LABEL: .long .L{{.*}}-.L.test
39 ; CHECK-NEXT: .short 0
40 ; 3 locations
41 ; CHECK-NEXT: .short 3
42 ; Loc 0: Register
43 ; CHECK-NEXT: .byte 1
44 ; CHECK-NEXT: .byte 4
45 ; CHECK-NEXT: .short {{[0-9]+}}
46 ; CHECK-NEXT: .long 0
47 ; Loc 1: Register
48 ; CHECK-NEXT: .byte 1
49 ; CHECK-NEXT: .byte 4
50 ; CHECK-NEXT: .short {{[0-9]+}}
51 ; CHECK-NEXT: .long 0
52 ; Loc 2: Constant 3
53 ; CHECK-NEXT: .byte 4
54 ; CHECK-NEXT: .byte 8
55 ; CHECK-NEXT: .short 0
56 ; CHECK-NEXT: .long 3
57 define i64 @test() nounwind ssp uwtable {
58 entry:
59 call anyregcc void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 0, i32 24, i8* null, i32 2, i32 1, i32 2, i64 3)
60 ret i64 0
61 }
62
63 ; property access 1 - %obj is an anyreg call argument and should therefore be in a register
64 ; CHECK-LABEL: .long .L{{.*}}-.L.property_access1
65 ; CHECK-NEXT: .short 0
66 ; 2 locations
67 ; CHECK-NEXT: .short 2
68 ; Loc 0: Register <-- this is the return register
69 ; CHECK-NEXT: .byte 1
70 ; CHECK-NEXT: .byte 8
71 ; CHECK-NEXT: .short {{[0-9]+}}
72 ; CHECK-NEXT: .long 0
73 ; Loc 1: Register
74 ; CHECK-NEXT: .byte 1
75 ; CHECK-NEXT: .byte 8
76 ; CHECK-NEXT: .short {{[0-9]+}}
77 ; CHECK-NEXT: .long 0
78 define i64 @property_access1(i8* %obj) nounwind ssp uwtable {
79 entry:
80 %f = inttoptr i64 281474417671919 to i8*
81 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 1, i32 24, i8* %f, i32 1, i8* %obj)
82 ret i64 %ret
83 }
84
85 ; property access 2 - %obj is an anyreg call argument and should therefore be in a register
86 ; CHECK-LABEL: .long .L{{.*}}-.L.property_access2
87 ; CHECK-NEXT: .short 0
88 ; 2 locations
89 ; CHECK-NEXT: .short 2
90 ; Loc 0: Register <-- this is the return register
91 ; CHECK-NEXT: .byte 1
92 ; CHECK-NEXT: .byte 8
93 ; CHECK-NEXT: .short {{[0-9]+}}
94 ; CHECK-NEXT: .long 0
95 ; Loc 1: Register
96 ; CHECK-NEXT: .byte 1
97 ; CHECK-NEXT: .byte 8
98 ; CHECK-NEXT: .short {{[0-9]+}}
99 ; CHECK-NEXT: .long 0
100 define i64 @property_access2() nounwind ssp uwtable {
101 entry:
102 %obj = alloca i64, align 8
103 %f = inttoptr i64 281474417671919 to i8*
104 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 2, i32 24, i8* %f, i32 1, i64* %obj)
105 ret i64 %ret
106 }
107
108 ; property access 3 - %obj is a frame index
109 ; CHECK-LABEL: .long .L{{.*}}-.L.property_access3
110 ; CHECK-NEXT: .short 0
111 ; 2 locations
112 ; CHECK-NEXT: .short 2
113 ; Loc 0: Register <-- this is the return register
114 ; CHECK-NEXT: .byte 1
115 ; CHECK-NEXT: .byte 8
116 ; CHECK-NEXT: .short {{[0-9]+}}
117 ; CHECK-NEXT: .long 0
118 ; Loc 1: Direct FP - 8
119 ; CHECK-NEXT: .byte 2
120 ; CHECK-NEXT: .byte 8
121 ; CHECK-NEXT: .short 31
122 ; CHECK-NEXT: .long 112
123 define i64 @property_access3() nounwind ssp uwtable {
124 entry:
125 %obj = alloca i64, align 8
126 %f = inttoptr i64 281474417671919 to i8*
127 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 3, i32 24, i8* %f, i32 0, i64* %obj)
128 ret i64 %ret
129 }
130
131 ; anyreg_test1
132 ; CHECK-LABEL: .long .L{{.*}}-.L.anyreg_test1
133 ; CHECK-NEXT: .short 0
134 ; 14 locations
135 ; CHECK-NEXT: .short 14
136 ; Loc 0: Register <-- this is the return register
137 ; CHECK-NEXT: .byte 1
138 ; CHECK-NEXT: .byte 8
139 ; CHECK-NEXT: .short {{[0-9]+}}
140 ; CHECK-NEXT: .long 0
141 ; Loc 1: Register
142 ; CHECK-NEXT: .byte 1
143 ; CHECK-NEXT: .byte 8
144 ; CHECK-NEXT: .short {{[0-9]+}}
145 ; CHECK-NEXT: .long 0
146 ; Loc 2: Register
147 ; CHECK-NEXT: .byte 1
148 ; CHECK-NEXT: .byte 8
149 ; CHECK-NEXT: .short {{[0-9]+}}
150 ; CHECK-NEXT: .long 0
151 ; Loc 3: Register
152 ; CHECK-NEXT: .byte 1
153 ; CHECK-NEXT: .byte 8
154 ; CHECK-NEXT: .short {{[0-9]+}}
155 ; CHECK-NEXT: .long 0
156 ; Loc 4: Register
157 ; CHECK-NEXT: .byte 1
158 ; CHECK-NEXT: .byte 8
159 ; CHECK-NEXT: .short {{[0-9]+}}
160 ; CHECK-NEXT: .long 0
161 ; Loc 5: Register
162 ; CHECK-NEXT: .byte 1
163 ; CHECK-NEXT: .byte 8
164 ; CHECK-NEXT: .short {{[0-9]+}}
165 ; CHECK-NEXT: .long 0
166 ; Loc 6: Register
167 ; CHECK-NEXT: .byte 1
168 ; CHECK-NEXT: .byte 8
169 ; CHECK-NEXT: .short {{[0-9]+}}
170 ; CHECK-NEXT: .long 0
171 ; Loc 7: Register
172 ; CHECK-NEXT: .byte 1
173 ; CHECK-NEXT: .byte 8
174 ; CHECK-NEXT: .short {{[0-9]+}}
175 ; CHECK-NEXT: .long 0
176 ; Loc 8: Register
177 ; CHECK-NEXT: .byte 1
178 ; CHECK-NEXT: .byte 8
179 ; CHECK-NEXT: .short {{[0-9]+}}
180 ; CHECK-NEXT: .long 0
181 ; Loc 9: Register
182 ; CHECK-NEXT: .byte 1
183 ; CHECK-NEXT: .byte 8
184 ; CHECK-NEXT: .short {{[0-9]+}}
185 ; CHECK-NEXT: .long 0
186 ; Loc 10: Register
187 ; CHECK-NEXT: .byte 1
188 ; CHECK-NEXT: .byte 8
189 ; CHECK-NEXT: .short {{[0-9]+}}
190 ; CHECK-NEXT: .long 0
191 ; Loc 11: Register
192 ; CHECK-NEXT: .byte 1
193 ; CHECK-NEXT: .byte 8
194 ; CHECK-NEXT: .short {{[0-9]+}}
195 ; CHECK-NEXT: .long 0
196 ; Loc 12: Register
197 ; CHECK-NEXT: .byte 1
198 ; CHECK-NEXT: .byte 8
199 ; CHECK-NEXT: .short {{[0-9]+}}
200 ; CHECK-NEXT: .long 0
201 ; Loc 13: Register
202 ; CHECK-NEXT: .byte 1
203 ; CHECK-NEXT: .byte 8
204 ; CHECK-NEXT: .short {{[0-9]+}}
205 ; CHECK-NEXT: .long 0
206 define i64 @anyreg_test1(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable {
207 entry:
208 %f = inttoptr i64 281474417671919 to i8*
209 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 4, i32 24, i8* %f, i32 13, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13)
210 ret i64 %ret
211 }
212
213 ; anyreg_test2
214 ; CHECK-LABEL: .long .L{{.*}}-.L.anyreg_test2
215 ; CHECK-NEXT: .short 0
216 ; 14 locations
217 ; CHECK-NEXT: .short 14
218 ; Loc 0: Register <-- this is the return register
219 ; CHECK-NEXT: .byte 1
220 ; CHECK-NEXT: .byte 8
221 ; CHECK-NEXT: .short {{[0-9]+}}
222 ; CHECK-NEXT: .long 0
223 ; Loc 1: Register
224 ; CHECK-NEXT: .byte 1
225 ; CHECK-NEXT: .byte 8
226 ; CHECK-NEXT: .short {{[0-9]+}}
227 ; CHECK-NEXT: .long 0
228 ; Loc 2: Register
229 ; CHECK-NEXT: .byte 1
230 ; CHECK-NEXT: .byte 8
231 ; CHECK-NEXT: .short {{[0-9]+}}
232 ; CHECK-NEXT: .long 0
233 ; Loc 3: Register
234 ; CHECK-NEXT: .byte 1
235 ; CHECK-NEXT: .byte 8
236 ; CHECK-NEXT: .short {{[0-9]+}}
237 ; CHECK-NEXT: .long 0
238 ; Loc 4: Register
239 ; CHECK-NEXT: .byte 1
240 ; CHECK-NEXT: .byte 8
241 ; CHECK-NEXT: .short {{[0-9]+}}
242 ; CHECK-NEXT: .long 0
243 ; Loc 5: Register
244 ; CHECK-NEXT: .byte 1
245 ; CHECK-NEXT: .byte 8
246 ; CHECK-NEXT: .short {{[0-9]+}}
247 ; CHECK-NEXT: .long 0
248 ; Loc 6: Register
249 ; CHECK-NEXT: .byte 1
250 ; CHECK-NEXT: .byte 8
251 ; CHECK-NEXT: .short {{[0-9]+}}
252 ; CHECK-NEXT: .long 0
253 ; Loc 7: Register
254 ; CHECK-NEXT: .byte 1
255 ; CHECK-NEXT: .byte 8
256 ; CHECK-NEXT: .short {{[0-9]+}}
257 ; CHECK-NEXT: .long 0
258 ; Loc 8: Register
259 ; CHECK-NEXT: .byte 1
260 ; CHECK-NEXT: .byte 8
261 ; CHECK-NEXT: .short {{[0-9]+}}
262 ; CHECK-NEXT: .long 0
263 ; Loc 9: Register
264 ; CHECK-NEXT: .byte 1
265 ; CHECK-NEXT: .byte 8
266 ; CHECK-NEXT: .short {{[0-9]+}}
267 ; CHECK-NEXT: .long 0
268 ; Loc 10: Register
269 ; CHECK-NEXT: .byte 1
270 ; CHECK-NEXT: .byte 8
271 ; CHECK-NEXT: .short {{[0-9]+}}
272 ; CHECK-NEXT: .long 0
273 ; Loc 11: Register
274 ; CHECK-NEXT: .byte 1
275 ; CHECK-NEXT: .byte 8
276 ; CHECK-NEXT: .short {{[0-9]+}}
277 ; CHECK-NEXT: .long 0
278 ; Loc 12: Register
279 ; CHECK-NEXT: .byte 1
280 ; CHECK-NEXT: .byte 8
281 ; CHECK-NEXT: .short {{[0-9]+}}
282 ; CHECK-NEXT: .long 0
283 ; Loc 13: Register
284 ; CHECK-NEXT: .byte 1
285 ; CHECK-NEXT: .byte 8
286 ; CHECK-NEXT: .short {{[0-9]+}}
287 ; CHECK-NEXT: .long 0
288 define i64 @anyreg_test2(i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13) nounwind ssp uwtable {
289 entry:
290 %f = inttoptr i64 281474417671919 to i8*
291 %ret = call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 5, i32 24, i8* %f, i32 8, i8* %a1, i8* %a2, i8* %a3, i8* %a4, i8* %a5, i8* %a6, i8* %a7, i8* %a8, i8* %a9, i8* %a10, i8* %a11, i8* %a12, i8* %a13)
292 ret i64 %ret
293 }
294
295 ; Test spilling the return value of an anyregcc call.
296 ;
297 ; [JS] Assertion: "Folded a def to a non-store!"
298 ;
299 ; CHECK-LABEL: .long .L{{.*}}-.L.patchpoint_spilldef
300 ; CHECK-NEXT: .short 0
301 ; CHECK-NEXT: .short 3
302 ; Loc 0: Register (some register that will be spilled to the stack)
303 ; CHECK-NEXT: .byte 1
304 ; CHECK-NEXT: .byte 8
305 ; CHECK-NEXT: .short {{[0-9]+}}
306 ; CHECK-NEXT: .long 0
307 ; Loc 1: Register
308 ; CHECK-NEXT: .byte 1
309 ; CHECK-NEXT: .byte 8
310 ; CHECK-NEXT: .short {{[0-9]+}}
311 ; CHECK-NEXT: .long 0
312 ; Loc 1: Register
313 ; CHECK-NEXT: .byte 1
314 ; CHECK-NEXT: .byte 8
315 ; CHECK-NEXT: .short {{[0-9]+}}
316 ; CHECK-NEXT: .long 0
317 define i64 @patchpoint_spilldef(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
318 entry:
319 %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 12, i32 24, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2)
320 tail call void asm sideeffect "nop", "~{r0},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r14},~{r15},~{r16},~{r17
321 },~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
322 ret i64 %result
323 }
324
325 ; Test spilling the arguments of an anyregcc call.
326 ;
327 ; [JS] AnyRegCC argument ends up being spilled
328 ;
329 ; CHECK-LABEL: .long .L{{.*}}-.L.patchpoint_spillargs
330 ; CHECK-NEXT: .short 0
331 ; CHECK-NEXT: .short 5
332 ; Loc 0: Return a register
333 ; CHECK-NEXT: .byte 1
334 ; CHECK-NEXT: .byte 8
335 ; CHECK-NEXT: .short {{[0-9]+}}
336 ; CHECK-NEXT: .long 0
337 ; Loc 1: Arg0 in a Register
338 ; CHECK-NEXT: .byte 1
339 ; CHECK-NEXT: .byte 8
340 ; CHECK-NEXT: .short {{[0-9]+}}
341 ; CHECK-NEXT: .long 0
342 ; Loc 2: Arg1 in a Register
343 ; CHECK-NEXT: .byte 1
344 ; CHECK-NEXT: .byte 8
345 ; CHECK-NEXT: .short {{[0-9]+}}
346 ; CHECK-NEXT: .long 0
347 ; Loc 3: Arg2 spilled to FP -96
348 ; CHECK-NEXT: .byte 3
349 ; CHECK-NEXT: .byte 8
350 ; CHECK-NEXT: .short 31
351 ; CHECK-NEXT: .long 128
352 ; Loc 4: Arg3 spilled to FP - 88
353 ; CHECK-NEXT: .byte 3
354 ; CHECK-NEXT: .byte 8
355 ; CHECK-NEXT: .short 31
356 ; CHECK-NEXT: .long 136
357 define i64 @patchpoint_spillargs(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
358 entry:
359 tail call void asm sideeffect "nop", "~{r0},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r14},~{r15},~{r16},~{r17
360 },~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
361 %result = tail call anyregcc i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 13, i32 24, i8* inttoptr (i64 0 to i8*), i32 2, i64 %p1, i64 %p2, i64 %p3, i64 %p4)
362 ret i64 %result
363 }
364
365 declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
366 declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)
+0
-93
test/CodeGen/PowerPC/ppc64-patchpoint.ll less more
None ; RUN: llc < %s | FileCheck %s
1 ; RUN: llc -fast-isel -fast-isel-abort < %s | FileCheck %s
2 target datalayout = "E-m:e-i64:64-n32:64"
3 target triple = "powerpc64-unknown-linux-gnu"
4
5 ; Trivial patchpoint codegen
6 ;
7 define i64 @trivial_patchpoint_codegen(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
8 entry:
9 ; CHECK-LABEL: trivial_patchpoint_codegen:
10
11 ; CHECK: li 11, -8531
12 ; CHECK-NEXT: rldic 11, 11, 32, 16
13 ; CHECK-NEXT: oris 11, 11, 48879
14 ; CHECK-NEXT: ori 11, 11, 51966
15 ; CHECK-NEXT: mtctr 11
16 ; CHECK-NEXT: bctrl
17
18 ; CHECK: li 11, -8531
19 ; CHECK-NEXT: rldic 11, 11, 32, 16
20 ; CHECK-NEXT: oris 11, 11, 48879
21 ; CHECK-NEXT: ori 11, 11, 51967
22 ; CHECK-NEXT: mtctr 11
23 ; CHECK-NEXT: bctrl
24
25 ; CHECK: blr
26
27 %resolveCall2 = inttoptr i64 244837814094590 to i8*
28 %result = tail call i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 2, i32 24, i8* %resolveCall2, i32 4, i64 %p1, i64 %p2, i64 %p3, i64 %p4)
29 %resolveCall3 = inttoptr i64 244837814094591 to i8*
30 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 3, i32 24, i8* %resolveCall3, i32 2, i64 %p1, i64 %result)
31 ret i64 %result
32 }
33
34 ; Caller frame metadata with stackmaps. This should not be optimized
35 ; as a leaf function.
36 ;
37 ; CHECK-LABEL: caller_meta_leaf
38 ; CHECK: stdu 1, -80(1)
39 ; CHECK: Ltmp
40 ; CHECK: addi 1, 1, 80
41 ; CHECK: blr
42
43 define void @caller_meta_leaf() {
44 entry:
45 %metadata = alloca i64, i32 3, align 8
46 store i64 11, i64* %metadata
47 store i64 12, i64* %metadata
48 store i64 13, i64* %metadata
49 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 4, i32 0, i64* %metadata)
50 ret void
51 }
52
53 ; Test patchpoints reusing the same TargetConstant.
54 ; Assertion failed: (CI.getNumArgOperands() >= NumArgs + 4)
55 ; There is no way to verify this, since it depends on memory allocation.
56 ; But I think it's useful to include as a working example.
57 define i64 @testLowerConstant(i64 %arg, i64 %tmp2, i64 %tmp10, i64* %tmp33, i64 %tmp79) {
58 entry:
59 %tmp80 = add i64 %tmp79, -16
60 %tmp81 = inttoptr i64 %tmp80 to i64*
61 %tmp82 = load i64* %tmp81, align 8
62 tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 14, i32 8, i64 %arg, i64 %tmp2, i64 %tmp10, i64 %tmp82)
63 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 15, i32 32, i8* null, i32 3, i64 %arg, i64 %tmp10, i64 %tmp82)
64 %tmp83 = load i64* %tmp33, align 8
65 %tmp84 = add i64 %tmp83, -24
66 %tmp85 = inttoptr i64 %tmp84 to i64*
67 %tmp86 = load i64* %tmp85, align 8
68 tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 17, i32 8, i64 %arg, i64 %tmp10, i64 %tmp86)
69 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 18, i32 32, i8* null, i32 3, i64 %arg, i64 %tmp10, i64 %tmp86)
70 ret i64 10
71 }
72
73 ; Test small patchpoints that don't emit calls.
74 define void @small_patchpoint_codegen(i64 %p1, i64 %p2, i64 %p3, i64 %p4) {
75 entry:
76 ; CHECK-LABEL: small_patchpoint_codegen:
77 ; CHECK: Ltmp
78 ; CHECK: nop
79 ; CHECK-NEXT: nop
80 ; CHECK-NEXT: nop
81 ; CHECK-NEXT: nop
82 ; CHECK-NEXT: nop
83 ; CHECK-NOT: nop
84 ; CHECK: blr
85 %result = tail call i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 5, i32 20, i8* null, i32 2, i64 %p1, i64 %p2)
86 ret void
87 }
88
89 declare void @llvm.experimental.stackmap(i64, i32, ...)
90 declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
91 declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)
92
+0
-24
test/CodeGen/PowerPC/ppc64-stackmap-nops.ll less more
None ; RUN: llc < %s -mtriple=powerpc64-unknown-gnu-linux | FileCheck %s
1
2 define void @test_shadow_optimization() {
3 entry:
4 ; Expect 12 bytes worth of nops here rather than 32: With the shadow optimization
5 ; in place, 20 bytes will be consumed by the frame teardown and return instr.
6 ; CHECK-LABEL: test_shadow_optimization:
7
8 ; CHECK: nop
9 ; CHECK-NEXT: nop
10 ; CHECK-NEXT: nop
11 ; CHECK-NOT: nop
12 ; CHECK: addi 1, 1, 64
13 ; CHECK: ld [[REG1:[0-9]+]], 16(1)
14 ; CHECK: ld 31, -8(1)
15 ; CHECK: mtlr [[REG1]]
16 ; CHECK: blr
17
18 tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 0, i32 32)
19 ret void
20 }
21
22 declare void @llvm.experimental.stackmap(i64, i32, ...)
23
+0
-289
test/CodeGen/PowerPC/ppc64-stackmap.ll less more
None ; RUN: llc < %s | FileCheck %s
1 ;
2 ; Note: Print verbose stackmaps using -debug-only=stackmaps.
3
4 ; We are not getting the correct stack alignment when cross compiling for arm64.
5 ; So specify a datalayout here.
6 target datalayout = "E-m:e-i64:64-n32:64"
7 target triple = "powerpc64-unknown-linux-gnu"
8
9 ; CHECK-LABEL: .section .llvm_stackmaps
10 ; CHECK-NEXT: __LLVM_StackMaps:
11 ; Header
12 ; CHECK-NEXT: .byte 1
13 ; CHECK-NEXT: .byte 0
14 ; CHECK-NEXT: .short 0
15 ; Num Functions
16 ; CHECK-NEXT: .long 11
17 ; Num LargeConstants
18 ; CHECK-NEXT: .long 2
19 ; Num Callsites
20 ; CHECK-NEXT: .long 11
21
22 ; Functions and stack size
23 ; CHECK-NEXT: .quad constantargs
24 ; CHECK-NEXT: .quad 128
25 ; CHECK-NEXT: .quad osrinline
26 ; CHECK-NEXT: .quad 144
27 ; CHECK-NEXT: .quad osrcold
28 ; CHECK-NEXT: .quad 128
29 ; CHECK-NEXT: .quad propertyRead
30 ; CHECK-NEXT: .quad 128
31 ; CHECK-NEXT: .quad propertyWrite
32 ; CHECK-NEXT: .quad 128
33 ; CHECK-NEXT: .quad jsVoidCall
34 ; CHECK-NEXT: .quad 128
35 ; CHECK-NEXT: .quad jsIntCall
36 ; CHECK-NEXT: .quad 128
37 ; CHECK-NEXT: .quad spilledValue
38 ; CHECK-NEXT: .quad 320
39 ; CHECK-NEXT: .quad spilledStackMapValue
40 ; CHECK-NEXT: .quad 224
41 ; CHECK-NEXT: .quad liveConstant
42 ; CHECK-NEXT: .quad 64
43 ; CHECK-NEXT: .quad clobberLR
44 ; CHECK-NEXT: .quad 208
45
46 ; Num LargeConstants
47 ; CHECK-NEXT: .quad 4294967295
48 ; CHECK-NEXT: .quad 4294967296
49
50 ; Constant arguments
51 ;
52 ; CHECK-NEXT: .quad 1
53 ; CHECK-NEXT: .long .L{{.*}}-.L.constantargs
54 ; CHECK-NEXT: .short 0
55 ; CHECK-NEXT: .short 4
56 ; SmallConstant
57 ; CHECK-NEXT: .byte 4
58 ; CHECK-NEXT: .byte 8
59 ; CHECK-NEXT: .short 0
60 ; CHECK-NEXT: .long 65535
61 ; SmallConstant
62 ; CHECK-NEXT: .byte 4
63 ; CHECK-NEXT: .byte 8
64 ; CHECK-NEXT: .short 0
65 ; CHECK-NEXT: .long 65536
66 ; SmallConstant
67 ; CHECK-NEXT: .byte 5
68 ; CHECK-NEXT: .byte 8
69 ; CHECK-NEXT: .short 0
70 ; CHECK-NEXT: .long 0
71 ; LargeConstant at index 0
72 ; CHECK-NEXT: .byte 5
73 ; CHECK-NEXT: .byte 8
74 ; CHECK-NEXT: .short 0
75 ; CHECK-NEXT: .long 1
76
77 define void @constantargs() {
78 entry:
79 %0 = inttoptr i64 244837814094590 to i8*
80 tail call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 1, i32 24, i8* %0, i32 0, i64 65535, i64 65536, i64 4294967295, i64 4294967296)
81 ret void
82 }
83
84 ; Inline OSR Exit
85 ;
86 ; CHECK-LABEL: .long .L{{.*}}-.L.osrinline
87 ; CHECK-NEXT: .short 0
88 ; CHECK-NEXT: .short 2
89 ; CHECK-NEXT: .byte 1
90 ; CHECK-NEXT: .byte 8
91 ; CHECK-NEXT: .short {{[0-9]+}}
92 ; CHECK-NEXT: .long 0
93 ; CHECK-NEXT: .byte 1
94 ; CHECK-NEXT: .byte 8
95 ; CHECK-NEXT: .short {{[0-9]+}}
96 ; CHECK-NEXT: .long 0
97 define void @osrinline(i64 %a, i64 %b) {
98 entry:
99 ; Runtime void->void call.
100 call void inttoptr (i64 244837814094590 to void ()*)()
101 ; Followed by inline OSR patchpoint with 12-byte shadow and 2 live vars.
102 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 3, i32 12, i64 %a, i64 %b)
103 ret void
104 }
105
106 ; Cold OSR Exit
107 ;
108 ; 2 live variables in register.
109 ;
110 ; CHECK-LABEL: .long .L{{.*}}-.L.osrcold
111 ; CHECK-NEXT: .short 0
112 ; CHECK-NEXT: .short 2
113 ; CHECK-NEXT: .byte 1
114 ; CHECK-NEXT: .byte 8
115 ; CHECK-NEXT: .short {{[0-9]+}}
116 ; CHECK-NEXT: .long 0
117 ; CHECK-NEXT: .byte 1
118 ; CHECK-NEXT: .byte 8
119 ; CHECK-NEXT: .short {{[0-9]+}}
120 ; CHECK-NEXT: .long 0
121 define void @osrcold(i64 %a, i64 %b) {
122 entry:
123 %test = icmp slt i64 %a, %b
124 br i1 %test, label %ret, label %cold
125 cold:
126 ; OSR patchpoint with 12-byte nop-slide and 2 live vars.
127 %thunk = inttoptr i64 244837814094590 to i8*
128 call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 4, i32 24, i8* %thunk, i32 0, i64 %a, i64 %b)
129 unreachable
130 ret:
131 ret void
132 }
133
134 ; Property Read
135 ; CHECK-LABEL: .long .L{{.*}}-.L.propertyRead
136 ; CHECK-NEXT: .short 0
137 ; CHECK-NEXT: .short 0
138 ;
139 ; FIXME: There are currently no stackmap entries. After moving to
140 ; AnyRegCC, we will have entries for the object and return value.
141 define i64 @propertyRead(i64* %obj) {
142 entry:
143 %resolveRead = inttoptr i64 244837814094590 to i8*
144 %result = call i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 5, i32 24, i8* %resolveRead, i32 1, i64* %obj)
145 %add = add i64 %result, 3
146 ret i64 %add
147 }
148
149 ; Property Write
150 ; CHECK-LABEL: .long .L{{.*}}-.L.propertyWrite
151 ; CHECK-NEXT: .short 0
152 ; CHECK-NEXT: .short 2
153 ; CHECK-NEXT: .byte 1
154 ; CHECK-NEXT: .byte 8
155 ; CHECK-NEXT: .short {{[0-9]+}}
156 ; CHECK-NEXT: .long 0
157 ; CHECK-NEXT: .byte 1
158 ; CHECK-NEXT: .byte 8
159 ; CHECK-NEXT: .short {{[0-9]+}}
160 ; CHECK-NEXT: .long 0
161 define void @propertyWrite(i64 %dummy1, i64* %obj, i64 %dummy2, i64 %a) {
162 entry:
163 %resolveWrite = inttoptr i64 244837814094590 to i8*
164 call anyregcc void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 6, i32 24, i8* %resolveWrite, i32 2, i64* %obj, i64 %a)
165 ret void
166 }
167
168 ; Void JS Call
169 ;
170 ; 2 live variables in registers.
171 ;
172 ; CHECK-LABEL: .long .L{{.*}}-.L.jsVoidCall
173 ; CHECK-NEXT: .short 0
174 ; CHECK-NEXT: .short 2
175 ; CHECK-NEXT: .byte 1
176 ; CHECK-NEXT: .byte 8
177 ; CHECK-NEXT: .short {{[0-9]+}}
178 ; CHECK-NEXT: .long 0
179 ; CHECK-NEXT: .byte 1
180 ; CHECK-NEXT: .byte 8
181 ; CHECK-NEXT: .short {{[0-9]+}}
182 ; CHECK-NEXT: .long 0
183 define void @jsVoidCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
184 entry:
185 %resolveCall = inttoptr i64 244837814094590 to i8*
186 call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 7, i32 24, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
187 ret void
188 }
189
190 ; i64 JS Call
191 ;
192 ; 2 live variables in registers.
193 ;
194 ; CHECK-LABEL: .long .L{{.*}}-.L.jsIntCall
195 ; CHECK-NEXT: .short 0
196 ; CHECK-NEXT: .short 2
197 ; CHECK-NEXT: .byte 1
198 ; CHECK-NEXT: .byte 8
199 ; CHECK-NEXT: .short {{[0-9]+}}
200 ; CHECK-NEXT: .long 0
201 ; CHECK-NEXT: .byte 1
202 ; CHECK-NEXT: .byte 8
203 ; CHECK-NEXT: .short {{[0-9]+}}
204 ; CHECK-NEXT: .long 0
205 define i64 @jsIntCall(i64 %dummy1, i64* %obj, i64 %arg, i64 %l1, i64 %l2) {
206 entry:
207 %resolveCall = inttoptr i64 244837814094590 to i8*
208 %result = call i64 (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.i64(i64 8, i32 24, i8* %resolveCall, i32 2, i64* %obj, i64 %arg, i64 %l1, i64 %l2)
209 %add = add i64 %result, 3
210 ret i64 %add
211 }
212
213 ; Spilled stack map values.
214 ;
215 ; Verify 28 stack map entries.
216 ;
217 ; CHECK-LABEL: .long .L{{.*}}-.L.spilledValue
218 ; CHECK-NEXT: .short 0
219 ; CHECK-NEXT: .short 28
220 ;
221 ; Check that at least one is a spilled entry from r31.
222 ; Location: Indirect FP + ...
223 ; CHECK: .byte 3
224 ; CHECK-NEXT: .byte 8
225 ; CHECK-NEXT: .short 31
226 define void @spilledValue(i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27) {
227 entry:
228 call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 11, i32 24, i8* null, i32 5, i64 %arg0, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27)
229 ret void
230 }
231
232 ; Spilled stack map values.
233 ;
234 ; Verify 30 stack map entries.
235 ;
236 ; CHECK-LABEL: .long .L{{.*}}-.L.spilledStackMapValue
237 ; CHECK-NEXT: .short 0
238 ; CHECK-NEXT: .short 30
239 ;
240 ; Check that at least one is a spilled entry from r31.
241 ; Location: Indirect FP + ...
242 ; CHECK: .byte 3
243 ; CHECK-NEXT: .byte 8
244 ; CHECK-NEXT: .short 31
245 define webkit_jscc void @spilledStackMapValue(i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27, i64 %l28, i64 %l29) {
246 entry:
247 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 12, i32 16, i64 %l0, i64 %l1, i64 %l2, i64 %l3, i64 %l4, i64 %l5, i64 %l6, i64 %l7, i64 %l8, i64 %l9, i64 %l10, i64 %l11, i64 %l12, i64 %l13, i64 %l14, i64 %l15, i64 %l16, i64 %l17, i64 %l18, i64 %l19, i64 %l20, i64 %l21, i64 %l22, i64 %l23, i64 %l24, i64 %l25, i64 %l26, i64 %l27, i64 %l28, i64 %l29)
248 ret void
249 }
250
251
252 ; Map a constant value.
253 ;
254 ; CHECK-LABEL: .long .L{{.*}}-.L.liveConstant
255 ; CHECK-NEXT: .short 0
256 ; 1 location
257 ; CHECK-NEXT: .short 1
258 ; Loc 0: SmallConstant
259 ; CHECK-NEXT: .byte 4
260 ; CHECK-NEXT: .byte 8
261 ; CHECK-NEXT: .short 0
262 ; CHECK-NEXT: .long 33
263
264 define void @liveConstant() {
265 tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 15, i32 8, i32 33)
266 ret void
267 }
268
269 ; Map a value when LR is the only free register.
270 ;
271 ; CHECK-LABEL: .long .L{{.*}}-.L.clobberLR
272 ; CHECK-NEXT: .short 0
273 ; 1 location
274 ; CHECK-NEXT: .short 1
275 ; Loc 0: Indirect FP (r31) - offset
276 ; CHECK-NEXT: .byte 3
277 ; CHECK-NEXT: .byte 4
278 ; CHECK-NEXT: .short 31
279 ; CHECK-NEXT: .long {{[0-9]+}}
280 define void @clobberLR(i32 %a) {
281 tail call void asm sideeffect "nop", "~{r0},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r14},~{r15},~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
282 tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 16, i32 8, i32 %a)
283 ret void
284 }
285
286 declare void @llvm.experimental.stackmap(i64, i32, ...)
287 declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
288 declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)