llvm.org GIT mirror llvm / 38c9ecd
Revert "Liveness Analysis Pass" This reverts commit r197254. This was an accidental merge of Juergen's patch. It will be checked in shortly, but wasn't meant to go in quite yet. Conflicts: include/llvm/CodeGen/StackMaps.h lib/CodeGen/StackMaps.cpp test/CodeGen/X86/stackmap-liveness.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197260 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 6 years ago
16 changed file(s) with 52 addition(s) and 508 deletion(s). Raw diff Collapse all Expand all
144144 /// to builtin \@llvm.returnaddress.
145145 bool ReturnAddressTaken;
146146
147 /// HasStackmap - This boolean keeps track of whether there is a call
148 /// to builtin \@llvm.experimental.stackmap or \@llvm.experimental.patchpoint.
149 bool HasStackMap;
150
151147 /// StackSize - The prolog/epilog code inserter calculates the final stack
152148 /// offsets for all of the fixed size objects, updating the Objects list
153149 /// above. It then updates StackSize to contain the number of bytes that need
238234 HasVarSizedObjects = false;
239235 FrameAddressTaken = false;
240236 ReturnAddressTaken = false;
241 HasStackMap = false;
242237 AdjustsStack = false;
243238 HasCalls = false;
244239 StackProtectorIdx = -1;
284279 bool isReturnAddressTaken() const { return ReturnAddressTaken; }
285280 void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
286281
287 /// hasStackMap - This method may be called any time after instruction
288 /// selection is complete to determine if there is a call to builtin
289 /// \@llvm.experimental.stackmap or \@llvm.experimental.patchpoint.
290 bool hasStackMap() const { return HasStackMap; }
291 void setHasStackMap(bool s = true) { HasStackMap = s; }
292
293282 /// getObjectIndexBegin - Return the minimum frame object index.
294283 ///
295284 int getObjectIndexBegin() const { return -NumFixedObjects; }
425425 OperandRecycler.deallocate(Cap, Array);
426426 }
427427
428 /// \brief Allocate and initialize a register mask with @p NumRegister bits.
429 uint32_t *allocateRegisterMask(unsigned NumRegister) {
430 unsigned Size = (NumRegister + 31) / 32;
431 uint32_t *Mask = Allocator.Allocate(Size);
432 for (unsigned i = 0; i != Size; ++i)
433 Mask[i] = 0;
434 return Mask;
435 }
436
437428 /// allocateMemRefsArray - Allocate an array to hold MachineMemOperand
438429 /// pointers. This array is owned by the MachineFunction.
439430 MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num);
5555 MO_GlobalAddress, ///< Address of a global value
5656 MO_BlockAddress, ///< Address of a basic block
5757 MO_RegisterMask, ///< Mask of preserved registers.
58 MO_RegisterLiveOut, ///< Mask of live-out registers.
5958 MO_Metadata, ///< Metadata reference (for debug info)
6059 MO_MCSymbol ///< MCSymbol reference (for debug/eh info)
6160 };
153152 const ConstantFP *CFP; // For MO_FPImmediate.
154153 const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
155154 int64_t ImmVal; // For MO_Immediate.
156 const uint32_t *RegMask; // For MO_RegisterMask and MO_RegisterLiveOut.
155 const uint32_t *RegMask; // For MO_RegisterMask.
157156 const MDNode *MD; // For MO_Metadata.
158157 MCSymbol *Sym; // For MO_MCSymbol
159158
246245 bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
247246 /// isRegMask - Tests if this is a MO_RegisterMask operand.
248247 bool isRegMask() const { return OpKind == MO_RegisterMask; }
249 /// isRegLiveOut - Tests if this is a MO_RegisterLiveOut operand.
250 bool isRegLiveOut() const { return OpKind == MO_RegisterLiveOut; }
251248 /// isMetadata - Tests if this is a MO_Metadata operand.
252249 bool isMetadata() const { return OpKind == MO_Metadata; }
253250 bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
475472 /// operand.
476473 const uint32_t *getRegMask() const {
477474 assert(isRegMask() && "Wrong MachineOperand accessor");
478 return Contents.RegMask;
479 }
480
481 /// getRegLiveOut - Returns a bit mask of live-out registers.
482 const uint32_t *getRegLiveOut() const {
483 assert(isRegLiveOut() && "Wrong MachineOperand accessor");
484475 return Contents.RegMask;
485476 }
486477
667658 Op.Contents.RegMask = Mask;
668659 return Op;
669660 }
670 static MachineOperand CreateRegLiveOut(const uint32_t *Mask) {
671 assert(Mask && "Missing live-out register mask");
672 MachineOperand Op(MachineOperand::MO_RegisterLiveOut);
673 Op.Contents.RegMask = Mask;
674 return Op;
675 }
676661 static MachineOperand CreateMetadata(const MDNode *Meta) {
677662 MachineOperand Op(MachineOperand::MO_Metadata);
678663 Op.Contents.MD = Meta;
567567 /// bundles (created earlier, e.g. during pre-RA scheduling).
568568 extern char &FinalizeMachineBundlesID;
569569
570 /// StackMapLiveness - This pass analyses the register live-out set of
571 /// stackmap/patchpoint intrinsics and attaches the calculated information to
572 /// the intrinsic for later emission to the StackMap.
573 extern char &StackMapLivenessID;
574
575570 } // End llvm namespace
576571
577572 #endif
+0
-67
include/llvm/CodeGen/StackMapLivenessAnalysis.h less more
None //===--- StackMapLivenessAnalysis - StackMap Liveness Analysis --*- 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 pass calculates the liveness for each basic block in a function and
10 // attaches the register live-out information to a stackmap or patchpoint
11 // intrinsic if present.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
16 #define LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
17
18 #include "llvm/CodeGen/LivePhysRegs.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
20
21
22 namespace llvm {
23
24 /// \brief This pass calculates the liveness information for each basic block in
25 /// a function and attaches the register live-out information to a stackmap or
26 /// patchpoint intrinsic if present.
27 ///
28 /// This is an optional pass that has to be explicitely enabled via the
29 /// -enable-stackmap-liveness flag. The pass skips functions that don't have any
30 /// stackmap or patchpoint intrinsics. The information provided by this pass is
31 /// optional and not required by the aformentioned intrinsics to function.
32 class StackMapLiveness : public MachineFunctionPass {
33 MachineFunction *MF;
34 const TargetRegisterInfo *TRI;
35 LivePhysRegs LiveRegs;
36 public:
37 static char ID;
38
39 /// \brief Default construct and initialize the pass.
40 StackMapLiveness();
41
42 /// \brief Tell the pass manager which passes we depend on and what
43 /// information we preserve.
44 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
45
46 /// \brief Calculate the liveness information for the given machine function.
47 virtual bool runOnMachineFunction(MachineFunction &MF);
48
49 private:
50 /// \brief Performs the actual liveness calculation for the function.
51 bool calculateLiveness();
52
53 /// \brief Add the current register live set to the instruction.
54 void addLiveOutSetToMI(MachineInstr &MI);
55
56 /// \brief Create a register mask and initialize it with the registers from
57 /// the register live set.
58 uint32_t *createRegisterMask() const;
59
60 /// \brief Print the current register live set for debugging.
61 void printLiveOutSet(raw_ostream &OS) const;
62 };
63
64 } // end llvm namespace
65
66 #endif // end LLVM_CODEGEN_STACKMAP_LIVENESS_ANALYSIS_H
9292 : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {}
9393 };
9494
95 struct LiveOutReg {
96 unsigned short Reg;
97 unsigned short RegNo;
98 unsigned short Size;
99
100 LiveOutReg() : Reg(0), RegNo(0), Size(0) {}
101 LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size)
102 : Reg(Reg), RegNo(RegNo), Size(Size) {}
103
104 // Only sort by the dwarf register number.
105 bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; }
106 static bool isInvalid(const LiveOutReg &LO) { return LO.Reg == 0; }
107 };
108
10995 // OpTypes are used to encode information about the following logical
11096 // operand (which may consist of several MachineOperands) for the
11197 // OpParser.
128114
129115 private:
130116 typedef SmallVector LocationVec;
131 typedef SmallVector LiveOutVec;
132117
133118 struct CallsiteInfo {
134119 const MCExpr *CSOffsetExpr;
135120 uint64_t ID;
136121 LocationVec Locations;
137 LiveOutVec LiveOuts;
138122 CallsiteInfo() : CSOffsetExpr(0), ID(0) {}
139123 CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
140 LocationVec &Locations, LiveOutVec &LiveOuts)
141 : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations),
142 LiveOuts(LiveOuts) {}
124 LocationVec Locations)
125 : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations) {}
143126 };
144127
145128 typedef std::vector CallsiteInfoList;
170153
171154 std::pair
172155 parseOperand(MachineInstr::const_mop_iterator MOI,
173 MachineInstr::const_mop_iterator MOE) const;
156 MachineInstr::const_mop_iterator MOE);
174157
175 /// \brief Create a live-out register record for the given register @p Reg.
176 LiveOutReg createLiveOutReg(unsigned Reg, const MCRegisterInfo &MCRI,
177 const TargetRegisterInfo *TRI) const;
178
179 /// \brief Parse the register live-out mask and return a vector of live-out
180 /// registers that need to be recorded in the stackmap.
181 LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const;
182158
183159 /// This should be called by the MC lowering code _immediately_ before
184160 /// lowering the MI to an MCInst. It records where the operands for the
265265 void initializeSLPVectorizerPass(PassRegistry&);
266266 void initializeBBVectorizePass(PassRegistry&);
267267 void initializeMachineFunctionPrinterPassPass(PassRegistry&);
268 void initializeStackMapLivenessPass(PassRegistry&);
269268 }
270269
271270 #endif
9696 StackColoring.cpp
9797 StackProtector.cpp
9898 StackSlotColoring.cpp
99 StackMapLivenessAnalysis.cpp
10099 StackMaps.cpp
101100 TailDuplication.cpp
102101 TargetFrameLoweringImpl.cpp
6868 initializeVirtRegRewriterPass(Registry);
6969 initializeLowerIntrinsicsPass(Registry);
7070 initializeMachineFunctionPrinterPassPass(Registry);
71 initializeStackMapLivenessPass(Registry);
7271 }
7372
7473 void LLVMInitializeCodeGen(LLVMPassRegistryRef R) {
198198 case MachineOperand::MO_BlockAddress:
199199 return getBlockAddress() == Other.getBlockAddress() &&
200200 getOffset() == Other.getOffset();
201 case MachineOperand::MO_RegisterMask:
202 case MachineOperand::MO_RegisterLiveOut:
201 case MO_RegisterMask:
203202 return getRegMask() == Other.getRegMask();
204203 case MachineOperand::MO_MCSymbol:
205204 return getMCSymbol() == Other.getMCSymbol();
241240 return hash_combine(MO.getType(), MO.getTargetFlags(),
242241 MO.getBlockAddress(), MO.getOffset());
243242 case MachineOperand::MO_RegisterMask:
244 case MachineOperand::MO_RegisterLiveOut:
245243 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
246244 case MachineOperand::MO_Metadata:
247245 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
369367 case MachineOperand::MO_RegisterMask:
370368 OS << "";
371369 break;
372 case MachineOperand::MO_RegisterLiveOut:
373 OS << "";
374 break;
375370 case MachineOperand::MO_Metadata:
376371 OS << '<';
377372 WriteAsOperand(OS, getMetadata(), /*PrintType=*/false);
6868 cl::desc("Disable Codegen Prepare"));
6969 static cl::opt DisableCopyProp("disable-copyprop", cl::Hidden,
7070 cl::desc("Disable Copy Propagation pass"));
71 static cl::opt EnableStackMapLiveness("enable-stackmap-liveness",
72 cl::Hidden, cl::desc("Enable StackMap Liveness Analysis Pass"));
7371 static cl::opt PrintLSR("print-lsr-output", cl::Hidden,
7472 cl::desc("Print LLVM IR produced by the loop-reduce pass"));
7573 static cl::opt PrintISelInput("print-isel-input", cl::Hidden,
537535
538536 if (addPreEmitPass())
539537 printAndVerify("After PreEmit passes");
540
541 if (EnableStackMapLiveness)
542 addPass(&StackMapLivenessID);
543538 }
544539
545540 /// Add passes that optimize machine instructions in SSA form.
68856885 DAG.ReplaceAllUsesWith(Call, MN);
68866886
68876887 DAG.DeleteNode(Call);
6888
6889 // Inform the Frame Information that we have a stackmap in this function.
6890 FuncInfo.MF->getFrameInfo()->setHasStackMap();
68916888 }
68926889
68936890 /// \brief Lower llvm.experimental.patchpoint directly to its target opcode.
70277024 } else
70287025 DAG.ReplaceAllUsesWith(Call, MN);
70297026 DAG.DeleteNode(Call);
7030
7031 // Inform the Frame Information that we have a stackmap in this function.
7032 FuncInfo.MF->getFrameInfo()->setHasStackMap();
70337027 }
70347028
70357029 /// TargetLowering::LowerCallTo - This is the default LowerCallTo
+0
-128
lib/CodeGen/StackMapLivenessAnalysis.cpp less more
None //===-- StackMapLivenessAnalysis.cpp - StackMap live Out Analysis ----------===//
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 implements the StackMap Liveness analysis pass. The pass calculates
10 // the liveness for each basic block in a function and attaches the register
11 // live-out information to a stackmap or patchpoint intrinsic if present.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "stackmaps"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
20 #include "llvm/CodeGen/Passes.h"
21 #include "llvm/CodeGen/StackMapLivenessAnalysis.h"
22 #include "llvm/Support/Debug.h"
23
24 using namespace llvm;
25
26
27 STATISTIC(NumStackMapFuncVisited, "Number of functions visited");
28 STATISTIC(NumStackMapFuncSkipped, "Number of functions skipped");
29 STATISTIC(NumBBsVisited, "Number of basic blocks visited");
30 STATISTIC(NumBBsHaveNoStackmap, "Number of basic blocks with no stackmap");
31 STATISTIC(NumStackMaps, "Number of StackMaps visited");
32
33 char StackMapLiveness::ID = 0;
34 char &llvm::StackMapLivenessID = StackMapLiveness::ID;
35 INITIALIZE_PASS(StackMapLiveness, "stackmap-liveness",
36 "StackMap Liveness Analysis", false, false)
37
38 /// Default construct and initialize the pass.
39 StackMapLiveness::StackMapLiveness() : MachineFunctionPass(ID) {
40 initializeStackMapLivenessPass(*PassRegistry::getPassRegistry());
41 }
42
43 /// Tell the pass manager which passes we depend on and what information we
44 /// preserve.
45 void StackMapLiveness::getAnalysisUsage(AnalysisUsage &AU) const {
46 // We preserve all information.
47 AU.setPreservesAll();
48 AU.setPreservesCFG();
49 // Default dependencie for all MachineFunction passes.
50 AU.addRequired();
51 }
52
53 /// Calculate the liveness information for the given machine function.
54 bool StackMapLiveness::runOnMachineFunction(MachineFunction &_MF) {
55 DEBUG(dbgs() << "********** COMPUTING STACKMAP LIVENESS: "
56 << _MF.getName() << " **********\n");
57 MF = &_MF;
58 TRI = MF->getTarget().getRegisterInfo();
59 ++NumStackMapFuncVisited;
60
61 // Skip this function if there are no stackmaps.
62 if (!MF->getFrameInfo()->hasStackMap()) {
63 ++NumStackMapFuncSkipped;
64 return false;
65 }
66 return calculateLiveness();
67 }
68
69 /// Performs the actual liveness calculation for the function.
70 bool StackMapLiveness::calculateLiveness() {
71 bool HasChanged = false;
72 // For all basic blocks in the function.
73 for (MachineFunction::iterator MBBI = MF->begin(), MBBE = MF->end();
74 MBBI != MBBE; ++MBBI) {
75 DEBUG(dbgs() << "****** BB " << MBBI->getName() << " ******\n");
76 LiveRegs.init(TRI);
77 LiveRegs.addLiveOuts(MBBI);
78 bool HasStackMap = false;
79 // Reverse iterate over all instructions and add the current live register
80 // set to an instruction if we encounter a stackmap or patchpoint
81 // instruction.
82 for (MachineBasicBlock::reverse_iterator I = MBBI->rbegin(),
83 E = MBBI->rend(); I != E; ++I) {
84 if (I->getOpcode() == TargetOpcode::STACKMAP ||
85 I->getOpcode() == TargetOpcode::PATCHPOINT) {
86 addLiveOutSetToMI(*I);
87 HasChanged = true;
88 HasStackMap = true;
89 ++NumStackMaps;
90 }
91 LiveRegs.stepBackward(*I);
92 }
93 ++NumBBsVisited;
94 if (!HasStackMap)
95 ++NumBBsHaveNoStackmap;
96 }
97 return HasChanged;
98 }
99
100 /// Add the current register live set to the instruction.
101 void StackMapLiveness::addLiveOutSetToMI(MachineInstr &MI) {
102 uint32_t *Mask = createRegisterMask();
103 MachineOperand MO = MachineOperand::CreateRegLiveOut(Mask);
104 MI.addOperand(*MF, MO);
105 DEBUG(dbgs() << " " << MI);
106 DEBUG(printLiveOutSet(dbgs()));
107 }
108
109 /// Create a register mask and initialize it with the registers from the
110 /// register live set.
111 uint32_t *StackMapLiveness::createRegisterMask() const {
112 // The mask is owned and cleaned up by the Machine Function.
113 uint32_t *Mask = MF->allocateRegisterMask(TRI->getNumRegs());
114 for (LivePhysRegs::const_iterator RI = LiveRegs.begin(), RE = LiveRegs.end();
115 RI != RE; ++RI)
116 Mask[*RI / 32] |= 1U << (*RI % 32);
117 return Mask;
118 }
119
120 /// Print the current register live set for debugging.
121 void StackMapLiveness::printLiveOutSet(raw_ostream &OS) const {
122 OS << " Register live-out:";
123 for (LivePhysRegs::const_iterator RI = LiveRegs.begin(), RE = LiveRegs.end();
124 RI != RE; ++RI)
125 OS << " " << TRI->getName(*RI);
126 OS << "\n";
127 }
6767
6868 std::pair
6969 StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
70 MachineInstr::const_mop_iterator MOE) const {
70 MachineInstr::const_mop_iterator MOE) {
7171 const MachineOperand &MOP = *MOI;
72 assert((!MOP.isReg() || !MOP.isImplicit()) &&
73 "Implicit operands should not be processed.");
72 assert(!MOP.isRegMask() && (!MOP.isReg() || !MOP.isImplicit()) &&
73 "Register mask and implicit operands should not be processed.");
7474
7575 if (MOP.isImm()) {
7676 // Verify anyregcc
104104 }
105105 }
106106 }
107
108 if (MOP.isRegMask() || MOP.isRegLiveOut())
109 return std::make_pair(Location(), ++MOI);
110107
111108 // Otherwise this is a reg operand. The physical register number will
112109 // ultimately be encoded as a DWARF regno. The stack map also records the size
122119 Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI);
123120 }
124121
125 /// Go up the super-register chain until we hit a valid dwarf register number.
126 static short getDwarfRegNum(unsigned Reg, const MCRegisterInfo &MCRI,
127 const TargetRegisterInfo *TRI) {
128 int RegNo = MCRI.getDwarfRegNum(Reg, false);
129 for (MCSuperRegIterator SR(Reg, TRI);
130 SR.isValid() && RegNo < 0; ++SR)
131 RegNo = TRI->getDwarfRegNum(*SR, false);
132
133 assert(RegNo >= 0 && "Invalid Dwarf register number.");
134 return (unsigned short) RegNo;
135 }
136
137 /// Create a live-out register record for the given register Reg.
138 StackMaps::LiveOutReg
139 StackMaps::createLiveOutReg(unsigned Reg, const MCRegisterInfo &MCRI,
140 const TargetRegisterInfo *TRI) const {
141 unsigned RegNo = getDwarfRegNum(Reg, MCRI, TRI);
142 unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize();
143 unsigned LLVMRegNo = MCRI.getLLVMRegNum(RegNo, false);
144 unsigned SubRegIdx = MCRI.getSubRegIndex(LLVMRegNo, Reg);
145 unsigned Offset = 0;
146 if (SubRegIdx)
147 Offset = MCRI.getSubRegIdxOffset(SubRegIdx) / 8;
148
149 return LiveOutReg(Reg, RegNo, Offset + Size);
150 }
151
152 /// Parse the register live-out mask and return a vector of live-out registers
153 /// that need to be recorded in the stackmap.
154 StackMaps::LiveOutVec
155 StackMaps::parseRegisterLiveOutMask(const uint32_t *Mask) const {
156 assert(Mask && "No register mask specified");
157 const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo();
158 MCContext &OutContext = AP.OutStreamer.getContext();
159 const MCRegisterInfo &MCRI = *OutContext.getRegisterInfo();
160 LiveOutVec LiveOuts;
161
162 for (unsigned Reg = 0, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg)
163 if ((Mask[Reg / 32] >> Reg % 32) & 1)
164 LiveOuts.push_back(createLiveOutReg(Reg, MCRI, TRI));
165
166 std::sort(LiveOuts.begin(), LiveOuts.end());
167 for (LiveOutVec::iterator I = LiveOuts.begin(), E = LiveOuts.end();
168 I != E; ++I) {
169 if (!I->Reg)
170 continue;
171 for (LiveOutVec::iterator II = next(I); II != E; ++II) {
172 if (I->RegNo != II->RegNo)
173 break;
174 I->Size = std::max(I->Size, II->Size);
175 if (TRI->isSuperRegister(I->Reg, II->Reg))
176 I->Reg = II->Reg;
177 II->Reg = 0;
178 }
179 }
180 LiveOuts.erase(std::remove_if(LiveOuts.begin(), LiveOuts.end(),
181 LiveOutReg::isInvalid), LiveOuts.end());
182 return LiveOuts;
183 }
184
185122 void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
186123 MachineInstr::const_mop_iterator MOI,
187124 MachineInstr::const_mop_iterator MOE,
191128 MCSymbol *MILabel = OutContext.CreateTempSymbol();
192129 AP.OutStreamer.EmitLabel(MILabel);
193130
194 LocationVec Locations;
195 LiveOutVec LiveOuts;
131 LocationVec CallsiteLocs;
196132
197133 if (recordResult) {
198134 std::pair ParseResult =
201137 Location &Loc = ParseResult.first;
202138 assert(Loc.LocType == Location::Register &&
203139 "Stackmap return location must be a register.");
204 Locations.push_back(Loc);
140 CallsiteLocs.push_back(Loc);
205141 }
206142
207143 while (MOI != MOE) {
214150 Loc.Offset = ConstPool.getConstantIndex(Loc.Offset);
215151 }
216152
217 // Skip the register mask and register live-out mask
218 if (Loc.LocType != Location::Unprocessed)
219 Locations.push_back(Loc);
153 CallsiteLocs.push_back(Loc);
220154 }
221155
222156 const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub(
224158 MCSymbolRefExpr::Create(AP.CurrentFnSym, OutContext),
225159 OutContext);
226160
227 if (MOI->isRegLiveOut())
228 LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut());
229
230 CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, Locations, LiveOuts));
161 CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, CallsiteLocs));
231162 }
232163
233164 static MachineInstr::const_mop_iterator
234165 getStackMapEndMOP(MachineInstr::const_mop_iterator MOI,
235166 MachineInstr::const_mop_iterator MOE) {
236167 for (; MOI != MOE; ++MOI)
237 if (MOI->isRegLiveOut() || (MOI->isReg() && MOI->isImplicit()))
168 if (MOI->isRegMask() || (MOI->isReg() && MOI->isImplicit()))
238169 break;
170
239171 return MOI;
240172 }
241173
242174 void StackMaps::recordStackMap(const MachineInstr &MI) {
243 assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap");
175 assert(MI.getOpcode() == TargetOpcode::STACKMAP && "exected stackmap");
244176
245177 int64_t ID = MI.getOperand(0).getImm();
246178 recordStackMapOpers(MI, ID, llvm::next(MI.operands_begin(), 2),
249181 }
250182
251183 void StackMaps::recordPatchPoint(const MachineInstr &MI) {
252 assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint");
184 assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "exected stackmap");
253185
254186 PatchPointOpers opers(&MI);
255187 int64_t ID = opers.getMetaOper(PatchPointOpers::IDPos).getImm();
288220 /// uint16 : Dwarf RegNum
289221 /// int32 : Offset
290222 /// }
291 /// uint16 : NumLiveOuts
292 /// LiveOuts[NumLiveOuts]
293 /// uint16 : Dwarf RegNum
294 /// uint8 : Reserved
295 /// uint8 : Size in Bytes
296223 /// }
297224 ///
298225 /// Location Encoding, Type, Value:
345272
346273 uint64_t CallsiteID = CSII->ID;
347274 const LocationVec &CSLocs = CSII->Locations;
348 const LiveOutVec &LiveOuts = CSII->LiveOuts;
349275
350276 DEBUG(dbgs() << WSMP << "callsite " << CallsiteID << "\n");
351277
353279 // runtime than crash in case of in-process compilation. Currently, we do
354280 // simple overflow checks, but we may eventually communicate other
355281 // compilation errors this way.
356 if (CSLocs.size() > UINT16_MAX || LiveOuts.size() > UINT16_MAX) {
357 AP.OutStreamer.EmitIntValue(UINT64_MAX, 8); // Invalid ID.
282 if (CSLocs.size() > UINT16_MAX) {
283 AP.OutStreamer.EmitIntValue(UINT32_MAX, 8); // Invalid ID.
358284 AP.OutStreamer.EmitValue(CSII->CSOffsetExpr, 4);
359285 AP.OutStreamer.EmitIntValue(0, 2); // Reserved.
360286 AP.OutStreamer.EmitIntValue(0, 2); // 0 locations.
361 AP.OutStreamer.EmitIntValue(0, 2); // 0 live-out registers.
362287 continue;
363288 }
364289
435360 AP.OutStreamer.EmitIntValue(RegNo, 2);
436361 AP.OutStreamer.EmitIntValue(Offset, 4);
437362 }
438
439 DEBUG(dbgs() << WSMP << " has " << LiveOuts.size()
440 << " live-out registers\n");
441
442 AP.OutStreamer.EmitIntValue(LiveOuts.size(), 2);
443
444 operIdx = 0;
445 for (LiveOutVec::const_iterator LI = LiveOuts.begin(), LE = LiveOuts.end();
446 LI != LE; ++LI, ++operIdx) {
447 DEBUG(dbgs() << WSMP << " LO " << operIdx << ": "
448 << MCRI.getName(LI->Reg)
449 << " [encoding: .short " << LI->RegNo
450 << ", .byte 0, .byte " << LI->Size << "]\n");
451
452 AP.OutStreamer.EmitIntValue(LI->RegNo, 2);
453 AP.OutStreamer.EmitIntValue(0, 1);
454 AP.OutStreamer.EmitIntValue(LI->Size, 1);
455 }
456363 }
457364
458365 AP.OutStreamer.AddBlankLine();
+0
-85
test/CodeGen/X86/stackmap-liveness.ll less more
None ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -disable-fp-elim | FileCheck %s
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=corei7-avx -disable-fp-elim -enable-stackmap-liveness| FileCheck -check-prefix=LIVE %s
2 ;
3 ; Note: Print verbose stackmaps using -debug-only=stackmaps.
4
5 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
6 ; CHECK-NEXT: __LLVM_StackMaps:
7 ; CHECK-NEXT: .long 0
8 ; Num LargeConstants
9 ; CHECK-NEXT: .long 0
10 ; Num Callsites
11 ; CHECK-NEXT: .long 3
12
13 ; CHECK-LABEL: .long L{{.*}}-_liveness
14 ; CHECK-NEXT: .short 0
15 ; CHECK-NEXT: .short 0
16 ; CHECK-NEXT: .short 0
17 ; LIVE-LABEL: .long L{{.*}}-_liveness
18 ; LIVE-NEXT: .short 0
19 ; LIVE-NEXT: .short 0
20 ; LIVE-NEXT: .short 2
21 ; LIVE-NEXT: .short 7
22 ; LIVE-NEXT: .byte 0
23 ; LIVE-NEXT: .byte 8
24 ; LIVE-NEXT: .short 19
25 ; LIVE-NEXT: .byte 0
26 ; LIVE-NEXT: .byte 16
27
28 ; CHECK-LABEL: .long L{{.*}}-_liveness
29 ; CHECK-NEXT: .short 0
30 ; CHECK-NEXT: .short 0
31 ; CHECK-NEXT: .short 0
32 ; LIVE-LABEL: .long L{{.*}}-_liveness
33 ; LIVE-NEXT: .short 0
34 ; LIVE-NEXT: .short 0
35 ; LIVE-NEXT: .short 6
36 ; LIVE-NEXT: .short 0
37 ; LIVE-NEXT: .byte 0
38 ; LIVE-NEXT: .byte 2
39 ; LIVE-NEXT: .short 7
40 ; LIVE-NEXT: .byte 0
41 ; LIVE-NEXT: .byte 8
42 ; LIVE-NEXT: .short 8
43 ; LIVE-NEXT: .byte 0
44 ; LIVE-NEXT: .byte 8
45 ; LIVE-NEXT: .short 17
46 ; LIVE-NEXT: .byte 0
47 ; LIVE-NEXT: .byte 32
48 ; LIVE-NEXT: .short 18
49 ; LIVE-NEXT: .byte 0
50 ; LIVE-NEXT: .byte 32
51 ; LIVE-NEXT: .short 19
52 ; LIVE-NEXT: .byte 0
53 ; LIVE-NEXT: .byte 16
54
55 ; CHECK-LABEL: .long L{{.*}}-_liveness
56 ; CHECK-NEXT: .short 0
57 ; CHECK-NEXT: .short 0
58 ; CHECK-NEXT: .short 0
59 ; LIVE-LABEL: .long L{{.*}}-_liveness
60 ; LIVE-NEXT: .short 0
61 ; LIVE-NEXT: .short 0
62 ; LIVE-NEXT: .short 2
63 ; LIVE-NEXT: .short 7
64 ; LIVE-NEXT: .byte 0
65 ; LIVE-NEXT: .byte 8
66 ; LIVE-NEXT: .short 19
67 ; LIVE-NEXT: .byte 0
68 ; LIVE-NEXT: .byte 16
69 define void @liveness() {
70 entry:
71 %a1 = call <2 x double> asm sideeffect "", "={xmm2}"() nounwind
72 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 1, i32 5)
73 %a2 = call i64 asm sideeffect "", "={r8}"() nounwind
74 %a3 = call i8 asm sideeffect "", "={ah}"() nounwind
75 %a4 = call <4 x double> asm sideeffect "", "={ymm0}"() nounwind
76 %a5 = call <4 x double> asm sideeffect "", "={ymm1}"() nounwind
77 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 2, i32 5)
78 call void asm sideeffect "", "{r8},{ah},{ymm0},{ymm1}"(i64 %a2, i8 %a3, <4 x double> %a4, <4 x double> %a5) nounwind
79 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 3, i32 5)
80 call void asm sideeffect "", "{xmm2}"(<2 x double> %a1) nounwind
81 ret void
82 }
83
84 declare void @llvm.experimental.stackmap(i64, i32, ...)
182182 ;
183183 ; Verify 17 stack map entries.
184184 ;
185 ; CHECK-LABEL: .long L{{.*}}-_spilledValue
186 ; CHECK-NEXT: .short 0
187 ; CHECK-NEXT: .short 17
185 ; CHECK-LABEL:.long L{{.*}}-_spilledValue
186 ; CHECK-NEXT: .short 0
187 ; CHECK-NEXT: .short 17
188188 ;
189189 ; Check that at least one is a spilled entry from RBP.
190190 ; Location: Indirect RBP + ...
191 ; CHECK: .byte 3
192 ; CHECK-NEXT: .byte 8
193 ; CHECK-NEXT: .short 6
191 ; CHECK: .byte 3
192 ; CHECK-NEXT: .byte 8
193 ; CHECK-NEXT: .short 6
194194 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) {
195195 entry:
196196 call void (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i64 11, i32 15, 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)
201201 ;
202202 ; Verify 17 stack map entries.
203203 ;
204 ; CHECK-LABEL: .long L{{.*}}-_spilledStackMapValue
205 ; CHECK-NEXT: .short 0
206 ; CHECK-NEXT: .short 17
204 ; CHECK-LABEL: .long L{{.*}}-_spilledStackMapValue
205 ; CHECK-NEXT: .short 0
206 ; CHECK-NEXT: .short 17
207207 ;
208208 ; Check that at least one is a spilled entry from RBP.
209209 ; Location: Indirect RBP + ...
210 ; CHECK: .byte 3
211 ; CHECK-NEXT: .byte 8
212 ; CHECK-NEXT: .short 6
210 ; CHECK: .byte 3
211 ; CHECK-NEXT: .byte 8
212 ; CHECK-NEXT: .short 6
213213 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) {
214214 entry:
215215 call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 12, i32 15, 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)
218218
219219 ; Spill a subregister stackmap operand.
220220 ;
221 ; CHECK-LABEL: .long L{{.*}}-_spillSubReg
222 ; CHECK-NEXT: .short 0
221 ; CHECK-LABEL: .long L{{.*}}-_spillSubReg
222 ; CHECK-NEXT: .short 0
223223 ; 4 locations
224 ; CHECK-NEXT: .short 1
224 ; CHECK-NEXT: .short 1
225225 ;
226226 ; Check that the subregister operand is a 4-byte spill.
227227 ; Location: Indirect, 4-byte, RBP + ...
228 ; CHECK: .byte 3
229 ; CHECK-NEXT: .byte 4
230 ; CHECK-NEXT: .short 6
228 ; CHECK: .byte 3
229 ; CHECK-NEXT: .byte 4
230 ; CHECK-NEXT: .short 6
231231 define void @spillSubReg(i64 %arg) #0 {
232232 bb:
233233 br i1 undef, label %bb1, label %bb2
258258 ; Map a single byte subregister. There is no DWARF register number, so
259259 ; we expect the register to be encoded with the proper size and spill offset. We don't know which
260260 ;
261 ; CHECK-LABEL: .long L{{.*}}-_subRegOffset
262 ; CHECK-NEXT: .short 0
261 ; CHECK-LABEL: .long L{{.*}}-_subRegOffset
262 ; CHECK-NEXT: .short 0
263263 ; 2 locations
264 ; CHECK-NEXT: .short 2
264 ; CHECK-NEXT: .short 2
265265 ;
266266 ; Check that the subregister operands are 1-byte spills.
267267 ; Location 0: Register, 4-byte, AL
268 ; CHECK-NEXT: .byte 1
269 ; CHECK-NEXT: .byte 1
270 ; CHECK-NEXT: .short 0
271 ; CHECK-NEXT: .long 0
268 ; CHECK-NEXT: .byte 1
269 ; CHECK-NEXT: .byte 1
270 ; CHECK-NEXT: .short 0
271 ; CHECK-NEXT: .long 0
272272 ;
273273 ; Location 1: Register, 4-byte, BL
274 ; CHECK-NEXT: .byte 1
275 ; CHECK-NEXT: .byte 1
276 ; CHECK-NEXT: .short 3
277 ; CHECK-NEXT: .long 0
274 ; CHECK-NEXT: .byte 1
275 ; CHECK-NEXT: .byte 1
276 ; CHECK-NEXT: .short 3
277 ; CHECK-NEXT: .long 0
278278 define void @subRegOffset(i16 %arg) {
279279 %v = mul i16 %arg, 5
280280 %a0 = trunc i16 %v to i8
288288
289289 ; Map a constant value.
290290 ;
291 ; CHECK-LABEL: .long L{{.*}}-_liveConstant
292 ; CHECK-NEXT: .short 0
291 ; CHECK-LABEL: .long L{{.*}}-_liveConstant
292 ; CHECK-NEXT: .short 0
293293 ; 1 location
294 ; CHECK-NEXT: .short 1
294 ; CHECK-NEXT: .short 1
295295 ; Loc 0: SmallConstant
296296 ; CHECK-NEXT: .byte 4
297297 ; CHECK-NEXT: .byte 8
315315 ; CHECK-NEXT: .byte 8
316316 ; CHECK-NEXT: .short 6
317317 ; CHECK-NEXT: .long
318
318 ; CHECK-NEXT: .quad
319319 ; Callsite 17
320 ; CHECK-LABEL: .long L{{.*}}-_directFrameIdx
320 ; CHECK-NEXT: .long L{{.*}}-_directFrameIdx
321321 ; CHECK-NEXT: .short 0
322322 ; 2 locations
323323 ; CHECK-NEXT: .short 2