llvm.org GIT mirror llvm / 539e931
Liveness Analysis Pass git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197254 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 6 years ago
17 changed file(s) with 514 addition(s) and 78 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
147151 /// StackSize - The prolog/epilog code inserter calculates the final stack
148152 /// offsets for all of the fixed size objects, updating the Objects list
149153 /// above. It then updates StackSize to contain the number of bytes that need
234238 HasVarSizedObjects = false;
235239 FrameAddressTaken = false;
236240 ReturnAddressTaken = false;
241 HasStackMap = false;
237242 AdjustsStack = false;
238243 HasCalls = false;
239244 StackProtectorIdx = -1;
279284 bool isReturnAddressTaken() const { return ReturnAddressTaken; }
280285 void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
281286
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
282293 /// getObjectIndexBegin - Return the minimum frame object index.
283294 ///
284295 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
428437 /// allocateMemRefsArray - Allocate an array to hold MachineMemOperand
429438 /// pointers. This array is owned by the MachineFunction.
430439 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.
5859 MO_Metadata, ///< Metadata reference (for debug info)
5960 MO_MCSymbol ///< MCSymbol reference (for debug/eh info)
6061 };
152153 const ConstantFP *CFP; // For MO_FPImmediate.
153154 const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
154155 int64_t ImmVal; // For MO_Immediate.
155 const uint32_t *RegMask; // For MO_RegisterMask.
156 const uint32_t *RegMask; // For MO_RegisterMask and MO_RegisterLiveOut.
156157 const MDNode *MD; // For MO_Metadata.
157158 MCSymbol *Sym; // For MO_MCSymbol
158159
245246 bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
246247 /// isRegMask - Tests if this is a MO_RegisterMask operand.
247248 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; }
248251 /// isMetadata - Tests if this is a MO_Metadata operand.
249252 bool isMetadata() const { return OpKind == MO_Metadata; }
250253 bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
472475 /// operand.
473476 const uint32_t *getRegMask() const {
474477 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");
475484 return Contents.RegMask;
476485 }
477486
658667 Op.Contents.RegMask = Mask;
659668 return Op;
660669 }
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 }
661676 static MachineOperand CreateMetadata(const MDNode *Meta) {
662677 MachineOperand Op(MachineOperand::MO_Metadata);
663678 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
570575 } // End llvm namespace
571576
572577 #endif
0 //===--- 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
9191 : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {}
9292 };
9393
94 struct LiveOutReg {
95 unsigned short Reg;
96 unsigned short RegNo;
97 unsigned short Size;
98
99 LiveOutReg() : Reg(0), RegNo(0), Size(0) {}
100 LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size)
101 : Reg(Reg), RegNo(RegNo), Size(Size) {}
102
103 // Only sort by the dwarf register number.
104 bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; }
105 static bool isInvalid(const LiveOutReg &LO) { return LO.Reg == 0; }
106 };
107
94108 // OpTypes are used to encode information about the following logical
95109 // operand (which may consist of several MachineOperands) for the
96110 // OpParser.
113127
114128 private:
115129 typedef SmallVector LocationVec;
130 typedef SmallVector LiveOutVec;
116131
117132 struct CallsiteInfo {
118133 const MCExpr *CSOffsetExpr;
119134 unsigned ID;
120135 LocationVec Locations;
136 LiveOutVec LiveOuts;
121137 CallsiteInfo() : CSOffsetExpr(0), ID(0) {}
122138 CallsiteInfo(const MCExpr *CSOffsetExpr, unsigned ID,
123 LocationVec Locations)
124 : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations) {}
139 LocationVec &Locations, LiveOutVec &LiveOuts)
140 : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations),
141 LiveOuts(LiveOuts) {}
125142 };
126143
127144 typedef std::vector CallsiteInfoList;
153170 /// Parse
154171 std::pair
155172 parseOperand(MachineInstr::const_mop_iterator MOI,
156 MachineInstr::const_mop_iterator MOE);
157
173 MachineInstr::const_mop_iterator MOE) const;
174
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;
158182
159183 /// This should be called by the MC lowering code _immediately_ before
160184 /// 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&);
268269 }
269270
270271 #endif
9696 StackColoring.cpp
9797 StackProtector.cpp
9898 StackSlotColoring.cpp
99 StackMapLivenessAnalysis.cpp
99100 StackMaps.cpp
100101 TailDuplication.cpp
101102 TargetFrameLoweringImpl.cpp
6868 initializeVirtRegRewriterPass(Registry);
6969 initializeLowerIntrinsicsPass(Registry);
7070 initializeMachineFunctionPrinterPassPass(Registry);
71 initializeStackMapLivenessPass(Registry);
7172 }
7273
7374 void LLVMInitializeCodeGen(LLVMPassRegistryRef R) {
198198 case MachineOperand::MO_BlockAddress:
199199 return getBlockAddress() == Other.getBlockAddress() &&
200200 getOffset() == Other.getOffset();
201 case MO_RegisterMask:
201 case MachineOperand::MO_RegisterMask:
202 case MachineOperand::MO_RegisterLiveOut:
202203 return getRegMask() == Other.getRegMask();
203204 case MachineOperand::MO_MCSymbol:
204205 return getMCSymbol() == Other.getMCSymbol();
240241 return hash_combine(MO.getType(), MO.getTargetFlags(),
241242 MO.getBlockAddress(), MO.getOffset());
242243 case MachineOperand::MO_RegisterMask:
244 case MachineOperand::MO_RegisterLiveOut:
243245 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
244246 case MachineOperand::MO_Metadata:
245247 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
367369 case MachineOperand::MO_RegisterMask:
368370 OS << "";
369371 break;
372 case MachineOperand::MO_RegisterLiveOut:
373 OS << "";
374 break;
370375 case MachineOperand::MO_Metadata:
371376 OS << '<';
372377 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"));
7173 static cl::opt PrintLSR("print-lsr-output", cl::Hidden,
7274 cl::desc("Print LLVM IR produced by the loop-reduce pass"));
7375 static cl::opt PrintISelInput("print-isel-input", cl::Hidden,
535537
536538 if (addPreEmitPass())
537539 printAndVerify("After PreEmit passes");
540
541 if (EnableStackMapLiveness)
542 addPass(&StackMapLivenessID);
538543 }
539544
540545 /// 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();
68886891 }
68896892
68906893 /// \brief Lower llvm.experimental.patchpoint directly to its target opcode.
70247027 } else
70257028 DAG.ReplaceAllUsesWith(Call, MN);
70267029 DAG.DeleteNode(Call);
7030
7031 // Inform the Frame Information that we have a stackmap in this function.
7032 FuncInfo.MF->getFrameInfo()->setHasStackMap();
70277033 }
70287034
70297035 /// TargetLowering::LowerCallTo - This is the default LowerCallTo
0 //===-- 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) {
70 MachineInstr::const_mop_iterator MOE) const {
7171 const MachineOperand &MOP = *MOI;
72 assert(!MOP.isRegMask() && (!MOP.isReg() || !MOP.isImplicit()) &&
73 "Register mask and implicit operands should not be processed.");
72 assert((!MOP.isReg() || !MOP.isImplicit()) &&
73 "Implicit operands should not be processed.");
7474
7575 if (MOP.isImm()) {
7676 // Verify anyregcc
105105 }
106106 }
107107
108 if (MOP.isRegMask() || MOP.isRegLiveOut())
109 return std::make_pair(Location(), ++MOI);
110
108111 // Otherwise this is a reg operand. The physical register number will
109112 // ultimately be encoded as a DWARF regno. The stack map also records the size
110113 // of a spill slot that can hold the register content. (The runtime can
119122 Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI);
120123 }
121124
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
122185 void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint32_t ID,
123186 MachineInstr::const_mop_iterator MOI,
124187 MachineInstr::const_mop_iterator MOE,
128191 MCSymbol *MILabel = OutContext.CreateTempSymbol();
129192 AP.OutStreamer.EmitLabel(MILabel);
130193
131 LocationVec CallsiteLocs;
194 LocationVec Locations;
195 LiveOutVec LiveOuts;
132196
133197 if (recordResult) {
134198 std::pair ParseResult =
137201 Location &Loc = ParseResult.first;
138202 assert(Loc.LocType == Location::Register &&
139203 "Stackmap return location must be a register.");
140 CallsiteLocs.push_back(Loc);
204 Locations.push_back(Loc);
141205 }
142206
143207 while (MOI != MOE) {
150214 Loc.Offset = ConstPool.getConstantIndex(Loc.Offset);
151215 }
152216
153 CallsiteLocs.push_back(Loc);
217 // Skip the register mask and register live-out mask
218 if (Loc.LocType != Location::Unprocessed)
219 Locations.push_back(Loc);
154220 }
155221
156222 const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub(
158224 MCSymbolRefExpr::Create(AP.CurrentFnSym, OutContext),
159225 OutContext);
160226
161 CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, CallsiteLocs));
227 if (MOI->isRegLiveOut())
228 LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut());
229
230 CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, Locations, LiveOuts));
162231 }
163232
164233 static MachineInstr::const_mop_iterator
165234 getStackMapEndMOP(MachineInstr::const_mop_iterator MOI,
166235 MachineInstr::const_mop_iterator MOE) {
167236 for (; MOI != MOE; ++MOI)
168 if (MOI->isRegMask() || (MOI->isReg() && MOI->isImplicit()))
237 if (MOI->isRegLiveOut() || (MOI->isReg() && MOI->isImplicit()))
169238 break;
170
171239 return MOI;
172240 }
173241
174242 void StackMaps::recordStackMap(const MachineInstr &MI) {
175 assert(MI.getOpcode() == TargetOpcode::STACKMAP && "exected stackmap");
243 assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap");
176244
177245 int64_t ID = MI.getOperand(0).getImm();
178246 assert((int32_t)ID == ID && "Stack maps hold 32-bit IDs");
182250 }
183251
184252 void StackMaps::recordPatchPoint(const MachineInstr &MI) {
185 assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "exected stackmap");
253 assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint");
186254
187255 PatchPointOpers opers(&MI);
188256 int64_t ID = opers.getMetaOper(PatchPointOpers::IDPos).getImm();
221289 /// uint16 : Dwarf RegNum
222290 /// int32 : Offset
223291 /// }
292 /// uint16 : NumLiveOuts
293 /// LiveOuts[NumLiveOuts]
294 /// uint16 : Dwarf RegNum
295 /// uint8 : Reserved
296 /// uint8 : Size in Bytes
224297 /// }
225298 ///
226299 /// Location Encoding, Type, Value:
273346
274347 unsigned CallsiteID = CSII->ID;
275348 const LocationVec &CSLocs = CSII->Locations;
349 const LiveOutVec &LiveOuts = CSII->LiveOuts;
276350
277351 DEBUG(dbgs() << WSMP << "callsite " << CallsiteID << "\n");
278352
280354 // runtime than crash in case of in-process compilation. Currently, we do
281355 // simple overflow checks, but we may eventually communicate other
282356 // compilation errors this way.
283 if (CSLocs.size() > UINT16_MAX) {
357 if (CSLocs.size() > UINT16_MAX || LiveOuts.size() > UINT16_MAX) {
284358 AP.OutStreamer.EmitIntValue(UINT32_MAX, 4); // Invalid ID.
285359 AP.OutStreamer.EmitValue(CSII->CSOffsetExpr, 4);
286360 AP.OutStreamer.EmitIntValue(0, 2); // Reserved.
287361 AP.OutStreamer.EmitIntValue(0, 2); // 0 locations.
362 AP.OutStreamer.EmitIntValue(0, 2); // 0 live-out registers.
288363 continue;
289364 }
290365
361436 AP.OutStreamer.EmitIntValue(RegNo, 2);
362437 AP.OutStreamer.EmitIntValue(Offset, 4);
363438 }
439
440 DEBUG(dbgs() << WSMP << " has " << LiveOuts.size()
441 << " live-out registers\n");
442
443 AP.OutStreamer.EmitIntValue(LiveOuts.size(), 2);
444
445 operIdx = 0;
446 for (LiveOutVec::const_iterator LI = LiveOuts.begin(), LE = LiveOuts.end();
447 LI != LE; ++LI, ++operIdx) {
448 DEBUG(dbgs() << WSMP << " LO " << operIdx << ": "
449 << MCRI.getName(LI->Reg)
450 << " [encoding: .short " << LI->RegNo
451 << ", .byte 0, .byte " << LI->Size << "]\n");
452
453 AP.OutStreamer.EmitIntValue(LI->RegNo, 2);
454 AP.OutStreamer.EmitIntValue(0, 1);
455 AP.OutStreamer.EmitIntValue(LI->Size, 1);
456 }
364457 }
365458
366459 AP.OutStreamer.AddBlankLine();
1010 ; CHECK-NEXT: .long 8
1111
1212 ; test
13 ; CHECK-NEXT: .long 0
1413 ; CHECK-LABEL: .long L{{.*}}-_test
1514 ; CHECK-NEXT: .short 0
1615 ; 3 locations
3736 }
3837
3938 ; property access 1 - %obj is an anyreg call argument and should therefore be in a register
40 ; CHECK-NEXT: .long 1
4139 ; CHECK-LABEL: .long L{{.*}}-_property_access1
4240 ; CHECK-NEXT: .short 0
4341 ; 2 locations
6058 }
6159
6260 ; property access 2 - %obj is an anyreg call argument and should therefore be in a register
63 ; CHECK-NEXT: .long 2
6461 ; CHECK-LABEL: .long L{{.*}}-_property_access2
6562 ; CHECK-NEXT: .short 0
6663 ; 2 locations
8481 }
8582
8683 ; property access 3 - %obj is a frame index
87 ; CHECK-NEXT: .long 3
8884 ; CHECK-LABEL: .long L{{.*}}-_property_access3
8985 ; CHECK-NEXT: .short 0
9086 ; 2 locations
108104 }
109105
110106 ; anyreg_test1
111 ; CHECK-NEXT: .long 4
112107 ; CHECK-LABEL: .long L{{.*}}-_anyreg_test1
113108 ; CHECK-NEXT: .short 0
114109 ; 14 locations
191186 }
192187
193188 ; anyreg_test2
194 ; CHECK-NEXT: .long 5
195189 ; CHECK-LABEL: .long L{{.*}}-_anyreg_test2
196190 ; CHECK-NEXT: .short 0
197191 ; 14 locations
277271 ;
278272 ; [JS] Assertion: "Folded a def to a non-store!"
279273 ;
280 ; CHECK-LABEL: .long 12
281274 ; CHECK-LABEL: .long L{{.*}}-_patchpoint_spilldef
282275 ; CHECK-NEXT: .short 0
283276 ; CHECK-NEXT: .short 3
307300 ;
308301 ; [JS] AnyRegCC argument ends up being spilled
309302 ;
310 ; CHECK-LABEL: .long 13
311303 ; CHECK-LABEL: .long L{{.*}}-_patchpoint_spillargs
312304 ; CHECK-NEXT: .short 0
313305 ; CHECK-NEXT: .short 5
0 ; 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 (i32, i32, ...)* @llvm.experimental.stackmap(i32 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 (i32, i32, ...)* @llvm.experimental.stackmap(i32 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 (i32, i32, ...)* @llvm.experimental.stackmap(i32 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(i32, i32, ...)
4646
4747 ; Inline OSR Exit
4848 ;
49 ; CHECK-NEXT: .long 3
50 ; CHECK-NEXT: .long L{{.*}}-_osrinline
49 ; CHECK-LABEL: .long L{{.*}}-_osrinline
5150 ; CHECK-NEXT: .short 0
5251 ; CHECK-NEXT: .short 2
5352 ; CHECK-NEXT: .byte 1
7170 ;
7271 ; 2 live variables in register.
7372 ;
74 ; CHECK-NEXT: .long 4
75 ; CHECK-NEXT: .long L{{.*}}-_osrcold
73 ; CHECK-LABEL: .long L{{.*}}-_osrcold
7674 ; CHECK-NEXT: .short 0
7775 ; CHECK-NEXT: .short 2
7876 ; CHECK-NEXT: .byte 1
9795 }
9896
9997 ; Property Read
100 ; CHECK-NEXT: .long 5
101 ; CHECK-NEXT: .long L{{.*}}-_propertyRead
98 ; CHECK-LABEL: .long L{{.*}}-_propertyRead
10299 ; CHECK-NEXT: .short 0
103100 ; CHECK-NEXT: .short 2
104101 ; CHECK-NEXT: .byte 1
118115 }
119116
120117 ; Property Write
121 ; CHECK-NEXT: .long 6
122 ; CHECK-NEXT: .long L{{.*}}-_propertyWrite
118 ; CHECK-LABEL: .long L{{.*}}-_propertyWrite
123119 ; CHECK-NEXT: .short 0
124120 ; CHECK-NEXT: .short 2
125121 ; CHECK-NEXT: .byte 1
141137 ;
142138 ; 2 live variables in registers.
143139 ;
144 ; CHECK-NEXT: .long 7
145 ; CHECK-NEXT: .long L{{.*}}-_jsVoidCall
140 ; CHECK-LABEL: .long L{{.*}}-_jsVoidCall
146141 ; CHECK-NEXT: .short 0
147142 ; CHECK-NEXT: .short 2
148143 ; CHECK-NEXT: .byte 1
164159 ;
165160 ; 2 live variables in registers.
166161 ;
167 ; CHECK: .long 8
168 ; CHECK-NEXT: .long L{{.*}}-_jsIntCall
162 ; CHECK-LABEL: .long L{{.*}}-_jsIntCall
169163 ; CHECK-NEXT: .short 0
170164 ; CHECK-NEXT: .short 2
171165 ; CHECK-NEXT: .byte 1
188182 ;
189183 ; Verify 17 stack map entries.
190184 ;
191 ; CHECK: .long 11
192 ; CHECK-NEXT: .long L{{.*}}-_spilledValue
193 ; CHECK-NEXT: .short 0
194 ; CHECK-NEXT: .short 17
185 ; CHECK-LABEL: .long L{{.*}}-_spilledValue
186 ; CHECK-NEXT: .short 0
187 ; CHECK-NEXT: .short 17
195188 ;
196189 ; Check that at least one is a spilled entry from RBP.
197190 ; Location: Indirect RBP + ...
198 ; CHECK: .byte 3
199 ; CHECK-NEXT: .byte 8
200 ; CHECK-NEXT: .short 6
191 ; CHECK: .byte 3
192 ; CHECK-NEXT: .byte 8
193 ; CHECK-NEXT: .short 6
201194 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) {
202195 entry:
203196 call void (i32, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.void(i32 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)
208201 ;
209202 ; Verify 17 stack map entries.
210203 ;
211 ; CHECK: .long 12
212 ; CHECK-LABEL: .long L{{.*}}-_spilledStackMapValue
213 ; CHECK-NEXT: .short 0
214 ; CHECK-NEXT: .short 17
204 ; CHECK-LABEL: .long L{{.*}}-_spilledStackMapValue
205 ; CHECK-NEXT: .short 0
206 ; CHECK-NEXT: .short 17
215207 ;
216208 ; Check that at least one is a spilled entry from RBP.
217209 ; Location: Indirect RBP + ...
218 ; CHECK: .byte 3
219 ; CHECK-NEXT: .byte 8
220 ; CHECK-NEXT: .short 6
210 ; CHECK: .byte 3
211 ; CHECK-NEXT: .byte 8
212 ; CHECK-NEXT: .short 6
221213 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) {
222214 entry:
223215 call void (i32, i32, ...)* @llvm.experimental.stackmap(i32 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)
226218
227219 ; Spill a subregister stackmap operand.
228220 ;
229 ; CHECK: .long 13
230 ; CHECK-LABEL: .long L{{.*}}-_spillSubReg
231 ; CHECK-NEXT: .short 0
221 ; CHECK-LABEL: .long L{{.*}}-_spillSubReg
222 ; CHECK-NEXT: .short 0
232223 ; 4 locations
233 ; CHECK-NEXT: .short 1
224 ; CHECK-NEXT: .short 1
234225 ;
235226 ; Check that the subregister operand is a 4-byte spill.
236227 ; Location: Indirect, 4-byte, RBP + ...
237 ; CHECK: .byte 3
238 ; CHECK-NEXT: .byte 4
239 ; CHECK-NEXT: .short 6
228 ; CHECK: .byte 3
229 ; CHECK-NEXT: .byte 4
230 ; CHECK-NEXT: .short 6
240231 define void @spillSubReg(i64 %arg) #0 {
241232 bb:
242233 br i1 undef, label %bb1, label %bb2
267258 ; Map a single byte subregister. There is no DWARF register number, so
268259 ; we expect the register to be encoded with the proper size and spill offset. We don't know which
269260 ;
270 ; CHECK: .long 14
271 ; CHECK-LABEL: .long L{{.*}}-_subRegOffset
272 ; CHECK-NEXT: .short 0
261 ; CHECK-LABEL: .long L{{.*}}-_subRegOffset
262 ; CHECK-NEXT: .short 0
273263 ; 2 locations
274 ; CHECK-NEXT: .short 2
264 ; CHECK-NEXT: .short 2
275265 ;
276266 ; Check that the subregister operands are 1-byte spills.
277267 ; Location 0: Register, 4-byte, AL
278 ; CHECK-NEXT: .byte 1
279 ; CHECK-NEXT: .byte 1
280 ; CHECK-NEXT: .short 0
281 ; CHECK-NEXT: .long 0
268 ; CHECK-NEXT: .byte 1
269 ; CHECK-NEXT: .byte 1
270 ; CHECK-NEXT: .short 0
271 ; CHECK-NEXT: .long 0
282272 ;
283273 ; Location 1: Register, 4-byte, BL
284 ; CHECK-NEXT: .byte 1
285 ; CHECK-NEXT: .byte 1
286 ; CHECK-NEXT: .short 3
287 ; CHECK-NEXT: .long 0
274 ; CHECK-NEXT: .byte 1
275 ; CHECK-NEXT: .byte 1
276 ; CHECK-NEXT: .short 3
277 ; CHECK-NEXT: .long 0
288278 define void @subRegOffset(i16 %arg) {
289279 %v = mul i16 %arg, 5
290280 %a0 = trunc i16 %v to i8
298288
299289 ; Map a constant value.
300290 ;
301 ; CHECK: .long 15
302 ; CHECK-LABEL: .long L{{.*}}-_liveConstant
303 ; CHECK-NEXT: .short 0
291 ; CHECK-LABEL: .long L{{.*}}-_liveConstant
292 ; CHECK-NEXT: .short 0
304293 ; 1 location
305 ; CHECK-NEXT: .short 1
294 ; CHECK-NEXT: .short 1
306295 ; Loc 0: SmallConstant
307296 ; CHECK-NEXT: .byte 4
308297 ; CHECK-NEXT: .byte 8
317306 ; Directly map an alloca's address.
318307 ;
319308 ; Callsite 16
320 ; CHECK: .long 16
321309 ; CHECK-LABEL: .long L{{.*}}-_directFrameIdx
322310 ; CHECK-NEXT: .short 0
323311 ; 1 location
327315 ; CHECK-NEXT: .byte 8
328316 ; CHECK-NEXT: .short 6
329317 ; CHECK-NEXT: .long
318
330319 ; Callsite 17
331 ; CHECK-NEXT: .long 17
332 ; CHECK-NEXT: .long L{{.*}}-_directFrameIdx
320 ; CHECK-LABEL: .long L{{.*}}-_directFrameIdx
333321 ; CHECK-NEXT: .short 0
334322 ; 2 locations
335323 ; CHECK-NEXT: .short 2